学习SpringBoot遇到的错误
记录学习SpringBoot遇到的错误,方便再次遇到时回头检查。
<1>. 启动类(SpringBootApplication)放错位置
错误场景:MainApplication类不应放在默认的src.main.java下。
Error:
** WARNING ** : Your ApplicationContext is unlikely to start due to a @ComponentScan of the default package.
2022-04-25 12:13:48.622 WARN 14856 --- [ main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanDefinitionStoreException: Failed to read candidate component class: URL [jar:file:/D:/Maven/repository/org/springframework/boot/spring-boot-autoconfigure/2.5.3/spring-boot-autoconfigure-2.5.3.jar!/org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration$EmbeddedDatabaseConfiguration.class]; nested exception is java.lang.IllegalStateException: Could not evaluate condition on org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration$EmbeddedDatabaseConfiguration due to org/springframework/dao/DataAccessException not found. Make sure your own configuration does not rely on that class. This can also happen if you are @ComponentScanning a springframework package (e.g. if you put a @ComponentScan in the default package by mistake)
2022-04-25 12:13:48.627 INFO 14856 --- [ main] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2022-04-25 12:13:48.640 ERROR 14856 --- [ main] o.s.boot.SpringApplication : Application run failed
org.springframework.beans.factory.BeanDefinitionStoreException: Failed to read candidate component class: URL [jar:file:/D:/Maven/repository/org/springframework/boot/spring-boot-autoconfigure/2.5.3/spring-boot-autoconfigure-2.5.3.jar!/org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration$EmbeddedDatabaseConfiguration.class]; nested exception is java.lang.IllegalStateException: Could not evaluate condition on org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration$EmbeddedDatabaseConfiguration due to org/springframework/dao/DataAccessException not found. Make sure your own configuration does not rely on that class. This can also happen if you are @ComponentScanning a springframework package (**e.g. if you put a @ComponentScan in the default package by mistake**)
at org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider.scanCandidateComponents(ClassPathScanningCandidateComponentProvider.java:452) ~[spring-context-5.3.9.jar:5.3.9]
at org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider.findCandidateComponents(ClassPathScanningCandidateComponentProvider.java:315) ~[spring-context-5.3
解决:
<2>. Bean名字重复
错误场景: 下面图1中的@Configuration注解会默认生成一个以无参构造函数创建的Bean加入到容器中,且这个bean的名字是与类同名,开头字母小写,即person。图2,@Configuration搭配@Bean注解使用,也是生成一个Bean放到容器中,这个bean名字是如方法同名,即person。 这样就会有冲突。 图1: 图2:
Error:
Description:
The bean 'person', defined in class path resource [spring/boot/study/config/MyConfig.class], could not be registered. A bean with that name has already been defined in file [D:\SourceTree\repository\javapractice\SpringBoot\SpringBootStudy\target\classes\spring\boot\study\model\Person.class] and overriding is disabled.
Action:
Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true
解决: 其实上面的Action也有讲了解决方法,重新命名或者设置bean名可以覆盖。
<3>. 多个同类型但不同名Bean的处理方式
错误场景: 下图有3个Bean都是Person类型,但是Bean名字不同。第一个是无参构造函数创建的,@Autowired默认是以类型注入Bean,当我们简单用以下person注入Bean时,得到的Bean就是这个无参构造函数创建的Bean;当用person3获取Bean时,同样是存在3个相同类型的Bean,但前者(person)不报错,后者(person3)报错,尚不知为何。突然get到一个idea:难道是当同类型有多个Bean时,会判断容器中的Bean是否存在与我们定义的对象名(如person,person3)同名的Bean,存在则获取同名的,不存在就报错。 用下面三处代码测试了,果真如此(只是不知源码是哪个)。 这样的缺点是对象名与Bean名耦合了。我们还可以使用@Qualifier(“person”)指定注入的Bean的名字。也可以在我们声明Bean时使用@Primary指定一个主要的Bean,注入时使用的就是@Primary修饰的Bean。
@Autowired
Person person;
@Autowired
Person person3;
@Autowired
Person person_zhangSan;
@Autowired
@Qualifier("person")
Person person4;
@Bean
@Primary
public Person person_zhangSan(){
System.out.println("开始创建Person实例!");
return new Person("张三", "男", 19);
}
Error:
Description:
Field person3 in spring.boot.study.controller.HelloController required a single bean, but 3 were found:
- person: defined by method 'person' in class path resource [spring/boot/study/config/MyConfig.class]
- person_zhangSan: defined by method 'person_zhangSan' in class path resource [spring/boot/study/config/MyConfig.class]
- person_liSi: defined by method 'person_liSi' in class path resource [spring/boot/study/config/MyConfig.class]
Action:
Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed
解决: 使用@Primary定义个以Bean为primary;使用@Qualifier指定注入的Bean的名字;定义consumer的名字与容器中Bean名一致。
|