SpringBoot自动装配原理
1.@SpringBootApplication注解
我们发现自己的boot项目都有这个注解。进入里面可以发现有三个注解。
- @SpringBootConfiguration:我们点进去以后可以发现底层是Configuration注解,说白了就是支持JavaConfig的方式来进行配置(使用Configuration配置类等同于XML文件)。
- @EnableAutoConfiguration:开启自动配置功能
- @ComponentScan:这个注解就是扫描注解,默认是扫描当前类下的package。将@Controller/@Service/@Component/@Repository等注解加载到IOC容器中。
2.@EnableAutoConfiguration注解
EnableAutoConfiguration 只是一个简单地注解,自动装配核心功能的实现实际是通过 AutoConfigurationImportSelector类。
@Target({ ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage //作用:将main包下的所欲组件注册到容器中
@Import({ AutoConfigurationImportSelector.class}) //加载自动装配类 xxxAutoconfiguration
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default { };
String[] excludeName() default { };
}
AutoConfigurationImportSelector:加载自动装配类
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {
}
public interface DeferredImportSelector extends ImportSelector {
}
public interface ImportSelector {
String[] selectImports(AnnotationMetadata var1);
}
可以看出,AutoConfigurationImportSelector 类实现了 ImportSelector接口,也就实现了这个接口中的 selectImports方法,该方法主要用于获取所有符合条件的类的全限定类名,这些类需要被加载到 IoC 容器中。
private static final String[] NO_IMPORTS = new String[0];
public String[] selectImports(AnnotationMetadata annotationMetadata) {
// <1>.判断自动装配开关是否打开
if (!this.isEnabled(annotationMetadata)) {
return NO_IMPORTS;
} else {
//<2>.获取所有需要装配的bean
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(autoConfigurationMetadata, annotationMetadata);
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
}
我们回到@Import(AutoConfigurationImportSelector.class)这句代码上,再点进去AutoConfigurationImportSelector.class看看具体的实现是什么:
我们再进去看一下这些配置信息是从哪里来的(进去getCandidateConfigurations方法):
https://mmbiz.qpic.cn/mmbiz\_png/2BGWl1qPxib2bLwWq4Fic3YPhqribnowjDRbXf5vHJKUhvEvan3vZUdWLv8S7nymVZDBRB8wpfhBktDDElJsQ5ghQ/640?wx\_fmt=png&tp=webp&wxfrom=5&wx\_lazy=1&wx\_co=1
这里包装了一层,我们看到的只是通过SpringFactoriesLoader来加载,还没看到关键信息,继续进去:
3.简单梳理:
- FACTORIES_RESOURCE_LOCATION的值是META-INF/spring.factories
- Spring启动的时候会扫描所有jar路径下的META-INF/spring.factories,将其文件包装成Properties对象
- 从Properties对象获取到key值为EnableAutoConfiguration的数据,然后添加到容器里边。
最后我们会默认加载113个默认的配置类:
4.总结
@SpringBootApplication等同于下面三个注解:
- @SpringBootConfiguration
- @EnableAutoConfiguration
- @ComponentScan
其中@EnableAutoConfiguration是关键(启用自动配置),内部实际上就去加载META-INF/spring.factories文件的信息,然后筛选出以EnableAutoConfiguration为key的数据,加载到IOC容器中,实现自动配置功能!
还没有评论,来说两句吧...