在启动类上的SpringBootApplication复合注解中@EnableAutoConfiguration注解是自动装配的主要配置注解。
@EnableAutoConfiguration里面有两个主要注解:
- @AutoConfigurationPackage 默认扫描启动类同包及其子包的类的bean进行注册
- @Import({AutoConfigurationImportSelector.class}) 自动装配的主要实现
@Import注解的使用参考https://blog.csdn.net/weixin_45453628/article/details/124234317
这里自动装配使用的是 @Import一个类 该类实现了ImportSelector 重写selectImports方法该方法返回了String[]数组的对象,数组里面的类都会注入到spring容器当中
进入到AutoConfigurationImportSelector类中发现它实现了DeferredImportSelector接口,DeferredImportSelector又继承了ImportSelector接口,所以AutoConfigurationImportSelector间接实现了ImportSelector。
DeferredImportSelector 是延迟导入
在AutoConfigurationImportSelector搜索selectImports实现方法时会发现有两个,其中一个是实现ImportSelector的selectImports方法,还有一个是实现DeferredImportSelector的selectImports方法。
那他会调用哪个?
经过我的调试发现 默认调用public Iterable<Entry> selectImports(),也就是实现DeferredImportSelector的
DeferredImportSelector#Group的方法调用循序是process -> selectImports
process方法主要是通过getAutoConfigurationEntry方法获取autoConfigurationEntry自动装配的实体
getAutoConfigurationEntry里调用getCandidateConfigurations方法,在调用SpringFactoriesLoader.loadFactoryNames()
loadFactoryNames再调用 loadSpringFactories来加载spring.factories文件
classLoader.getResources("META-INF/spring.factories");
private static Map<String, List<String>> loadSpringFactories(ClassLoader classLoader) {Enumeration urls = classLoader.getResources("META-INF/spring.factories");while(urls.hasMoreElements()) {URL url = (URL)urls.nextElement();UrlResource resource = new UrlResource(url);Properties properties = PropertiesLoaderUtils.loadProperties(resource);Iterator var6 = properties.entrySet().iterator();while(var6.hasNext()) {Entry<?, ?> entry = (Entry)var6.next();String factoryTypeName = ((String)entry.getKey()).trim();String[] factoryImplementationNames = StringUtils.commaDelimitedListToStringArray((String)entry.getValue());}}}}
loadSpringFactories方法中会遍历所有包的类路径下的META-INF/spring.factories找出自动配置的配置类的全路径名
获取的全部全路径名要经过条件筛选getCandidateConfigurations获得可以用的全路径名,将他们封装成AutoConfigurationEntry
在selectImports还要再排除一遍和排序
最后返回经过一系列操作注册bean