#spring #spring-boot #spring-data-jpa
#весна #весна-загрузка #spring-data-jpa
Вопрос:
Не удается решить проблемы с тестовым приложением Spring Boot:
spring.bat init --artifactId=dbproto3 --boot-version=2.1.7.RELEASE --dependencies=jdbc,data-rest,web,thymeleaf,devtools,lombok,configuration-processor,security,data-jpa,data-jdbc,postgresql,actuator --description=dbproto3 --groupId=com.test --java-version=11 --name=dbproto3 --package-name=com.test.dbproto3 --version=0.0.1-SNAPSHOT
Это тестовое приложение, созданное путем изменения руководства «Доступ к данным с помощью MySQL» с официального сайта Spring. Первая версия (близкая к начальной: пустой springconfig, @Controller и @RequestMapping(path=»/ demo»), …) отлично работала, но моя версия генерирует исключение
Запустив его, я получаю исключение:
Exception in thread "restartedMain" java.lang.reflect.InvocationTargetException
2 . at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
3 . at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
4 . at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
5 . at java.base/java.lang.reflect.Method.invoke(Method.java:566)
6 . at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
7 . Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'mainController': Unsatisfied dependency expressed through field 'userRepository'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.test.dbproto3.UserRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
8 . at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:596)
9 . at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90)
10 . at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:374)
11 . at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1411)
12 . at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:592)
13 . at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515)
14 . at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
15 . at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
16 . at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
17 . at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
18 . at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:845)
19 . at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:877)
20 . at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549)
21 . at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:88)
22 . at com.test.dbproto3.Dbproto3Application.main(Dbproto3Application.java:18)
23 . ... 5 more
24 . Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.test.dbproto3.UserRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
25 . at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1658)
26 . at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1217)
27 . at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1171)
28 . at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:593)
29 . ... 19 more
Dbproto3Application:
@SpringBootApplication
2 . public class Dbproto3Application {
3 .
4 . public static void main(String[] args) {
5 . SpringApplication.run(Dbproto3Application.class, args);
6 .
7 . ApplicationContext javaConfigContext = new AnnotationConfigApplicationContext(SpringConfig.class);
8 .
9 . MainController mainControllerObj = (MainController) javaConfigContext.getBean("mainController");
10 .
11 . mainControllerObj.addNewUser();
12 . }
13 . }
SpringConfig:
1 . @Configuration
2 . public class SpringConfig {
3 . @Bean("mainController")
4 . public MainController createMainController() {
5 . return new MainController();
6 . }
7 . }
Пользователь:
1 . @Entity
2 . @Table(name = "userstab")
3 . public class User {
4 . @Id
5 . @GeneratedValue(strategy=GenerationType.AUTO)
6 . private Integer id;
7 .
8 . private String name;
9 .
10 . private String email;
11 .
12 . }
UserRepository:
1 . public interface UserRepository extends CrudRepository<User, Integer> {
2 .
3 . }
MainController:
3 . public class MainController {
4 .
5 . @Autowired
6 . private UserRepository userRepository;
7 .
8 .
9 . public void addNewUser() {
10 . User n = new User();
11 . n.setName("testuser");
12 . n.setEmail("testemail");
13 . System.out.println("addNewUser()");
14 . userRepository.save(n);
15 . }
16 .
17 . }
свойства приложения:
server.port = 8082
## default connection pool
spring.datasource.hikari.connectionTimeout=20000
spring.datasource.hikari.maximumPoolSize=5
## PostgreSQL
spring.datasource.url=jdbc:postgresql://localhost:5432/example_db
spring.datasource.username=someuser
spring.datasource.password=123456
spring.jpa.hibernate.ddl-auto=update
Ответ №1:
Я не смог увидеть никаких аннотаций для вашего интерфейса репозитория в коде, которым вы поделились.Даже если вы расширяете CrudRepository
интерфейс, чтобы создать свой собственный интерфейс. Spring boot должен понимать во время запуска, что ему необходимо предоставить реализацию по умолчанию для ваших объектов.Используйте аннотацию @Repository
в вашем интерфейсе, например :
@Repository
public interface UserRepository extends CrudRepository<User, Integer> {
}
Кроме того, вы создаете компонент контроллера каким-то странным способом, поэтому вы можете пытаться сделать что-то нетрадиционное, что означает, что простое использование @Autowired
в вашем основном классе приложения также может быть для вас немного затруднительным. Но я бы предложил это сделать. Вы используете AnnotationConfigApplicationContext
для создания компонента для вашего контроллера, но вы предоставляете только класс конфигурации, который вы создали для сканирования. Возможно, компонент для UserRepository, поскольку он создается springboot, отсутствует в контексте приложения, который вы создали с помощью AnnotationConfigApplicationContext
. Я думаю, что это отдельный контекст.
Комментарии:
1. spring.io/guides/gs/accessing-data-mysql — это начальное руководство. Данные Spring автоматически генерируют реализацию CRUD без
@Repository
. Добавление@Repository
ничего не меняет2. @asdfgh очевидно, что у вас этого не происходит, поэтому я попросил вас добавить аннотацию. Вероятно, из-за вашей структуры каталогов или того, где вы разместили свой основной класс приложения. Springboot обычно проверяет создание компонента, используя пакет, в котором находится основное приложение, в качестве корневого.
3. Я не использую
@Controller
, потому что мне нужно использовать репозиторий в пользовательском компоненте, который не является контроллером. Но я не могу понять, почему меняется класс с аннотированной конфигурацией на тормоза с конфигурацией Java@Autowired
4. Все классы находятся в одном каталоге
5. Если я удалю @Autowired, Spring Boot без проблем создаст компонент MainController, я могу получить его через getBean() и вызвать addNewUser().