本文基于SpringBoot 2.6.0分析,(但实际上目前所有版本都存在这个问题),使用@Component会导致spring.factories中的EnableAutoConfiguration无效
在spring.factories中通过org.springframework.boot.autoconfigure.EnableAutoConfiguration配置自动装配类时,bean名称是全类名。
-
加上如下两个注解都不会出现被实例化两次的问题:
@Configuration
,@Component
-
但使用
@Component
注解会导致在spring.factories
中配置的无效,bean名称变为类名首字母小写,而@Configuration
不会,原因是在做类路径bean扫描时,会过滤掉含
@Configuration
并配置在spring.factories
中的类,参见:org.springframework.boot.autoconfigure.AutoConfigurationExcludeFilter
,由AutoConfigurationImportSelector
去加载.
@Configuration
//@Component
public class MyCustomAutoConfiguration {
public MyCustomAutoConfiguration() {
System.out.println(MyCustomAutoConfiguration.class.getName() + " init...");
}
}
为什么类上标记@Component
会导致其在spring.factories
中配置无效 ???
原因在于Spring执行包扫描的时候,会将扫描的类包装成ConfigurationClass
进行解析,解析之前会从Map(ConfigurationClassParser#configurationClasses
)中获取判断之前是否已经解析过,如果已经解析过则跳过,解析之后会存放到Map中保存。当使用@Component
会被Spring扫描到, 之后AutoConfigurationImportSelector
加载spring.factories
中的EnableAutoConfiguration
时虽然能加载到,但是在处理时判断之前实际上已经处理过,所以不再被处理。