SpringBoot自动装配原理
SpringBoot自动装配原理
SpringBoot自动装配原理是怎么样的呢,不同的人可能有不同的理解,但作为程序员,最权威的就是看源码了,下面看下springboot相关的源码,理解一下SpringBoot自动装配原理
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
}
进入SpringBootApplication注解可以看到EnableAutoConfiguration注解
@Enable注解的主要作用把相关组件的Bean装配到IOC容器中
EnableAutoConfiguration注解
进入EnableAutoConfiguration注解 :
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
/**
* Exclude specific auto-configuration classes such that they will never be applied.
* @return the classes to exclude
*/
Class<?>[] exclude() default {};
/**
* Exclude specific auto-configuration class names such that they will never be
* applied.
* @return the class names to exclude
* @since 1.3.0
*/
String[] excludeName() default {};
}
@AutoConfigurationPackage的作用是把使用了该注解的类所在的包和子包下所有的组件扫描到SpringIOC容器中。@Import注解导入了一个AutoConfigurationImportSelector类,AutoConfigurationImportSelector实现配置类的导入
AutoConfigurationImportSelector
AutoConfigurationImportSelector实现了ImportSelector接口 selectImports方法返回一个String数组,数组中指定需要装配到IOC容器中
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return NO_IMPORTS;
}
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
.loadMetadata(this.beanClassLoader);
AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(
autoConfigurationMetadata, annotationMetadata);
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
- AutoConfigurationMetadataLoader.loadMetadata从META-INF/spring-autoconfigure-metadata.properties中加载自动装配的条件元数据,就是只有满足条件的Bean才能够进行装配。
- 收集符合条件的配置类autoConfigurationEntry.getConfigurations(),完成自动装配
AutoConfigurationImportSelector中不执行selectImports方法,而是通过ConfigurationClassPostProcessor的processConfigBeanDefinitions方法进行扫描和注册所有配置类的Bean。
protected AutoConfigurationEntry getAutoConfigurationEntry(
AutoConfigurationMetadata autoConfigurationMetadata,
AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
}
AnnotationAttributes attributes = getAttributes(annotationMetadata);
List<String> configurations = getCandidateConfigurations(annotationMetadata,
attributes);
configurations = removeDuplicates(configurations);
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = filter(configurations, autoConfigurationMetadata);
fireAutoConfigurationImportEvents(configurations, exclusions);
return new AutoConfigurationEntry(configurations, exclusions);
}
- getAttributes获得@EnableAutoConfiguration注解中的属性exclude excludeName等
- getCandidateConfigurations()获得所有自动装配的配置类
- removeDuplicates()方法去除重复的配置项
- getExclusions方法根据@EnableAutoConfiguration注解中配置的exclude属性,把不需要自动装配的配置类移除。
- fireAutoConfigurationImportEvents方法广播事件
- 最后返回经过多层判断和过滤之后的配置类集合。
getCandidateConfigurations()方法
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata,
AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(
getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());
Assert.notEmpty(configurations,
"No auto configuration classes found in META-INF/spring.factories. If you "
+ "are using a custom packaging, make sure that file is correct.");
return configurations;
}
SpringFactoriesLoader扫描classpath下的META-INF/spring.factories文件,根据Key得到对应的value值。
总结
- 通过@Import实现配置类的导入
- AutoConfigurationImportSelector类实现ImportSelector接口,重写selectImports方法,用于实现选择性批量配置类的装配
- 通过Spring提供的SpringFactoriesLoader机制,扫描classpath路径下的META-INF/spring.factories文件,读取需要实现自动装配的配置类
- 通过条件筛选,把不符合条件的配置类移除,最终完成自动装配。
好了 这就是SpringBoot自动装配原理,给大家简简单单的分析了一下,如果你觉得还不错的话,欢迎给大家留言和点赞,大家的赞是对我最大的鼓励,我将继续更文,提升自己的同时分享更多的好文章。
- 点赞
- 收藏
- 关注作者
评论(0)