记录学习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:SourceTreerepositoryjavapracticeSpringBootSpringBootStudytargetclassesspringbootstudymodelPerson.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都是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;
// 容器中存在于对象person_zhangSan同名的Bean,则注入同名的那个
@Autowired
Person person_zhangSan;
// 指定注入的Bean的名字
@Autowired
@Qualifier("person")
Person person4;
// 使用@Primary,存在多个Bean时默认使用Primary的
@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名一致。



