SpringBoot 的核心注解 SpringBootApplication 。
可以把 @SpringBootApplication看作是 @Configuration、@EnableAutoConfiguration、@ComponentScan 注解的集合。根据 SpringBoot 官网,这三个注解的作用分别是:
@EnableAutoConfiguration:启用 SpringBoot 的自动配置机制
@Configuration:允许在上下文中注册额外的 bean 或导入其他配置类
@ComponentScan: 扫描被@Component (@Service,@Controller)注解的 bean,注解默认会扫描启动类所在的包下所有的类 ,可以自定义不扫描某些 bean。如下图所示,容器中将排除TypeExcludeFilter和AutoConfigurationExcludeFilter。
@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 容器中。
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
//判断自动装配开关是否打开
if (!isEnabled(annotationMetadata)) {
return NO_IMPORTS;
}
//获取所有需要装配的bean
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
.loadMetadata(this.beanClassLoader);
AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(autoConfigurationMetadata,
annotationMetadata);//重点关注
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
getAutoConfigurationEntry方法调用链如下为:
getAutoConfigurationEntry(autoConfigurationMetadata,
annotationMetadata);→getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes)→ SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass()→SpringFactoriesLoader.loadSpringFactories(classLoader)
接下来看下getAutoConfigurationEntry()的源码
protected AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata,
AnnotationMetadata annotationMetadata) {
//判断自动装配开关是否打开。默认spring.boot.enableautoconfiguration=true,可在 application.properties 或 application.yml 中设置
if (!isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
}
//用于获取EnableAutoConfiguration注解中的 exclude 和 excludeName。
AnnotationAttributes attributes = getAttributes(annotationMetadata);
//获取需要自动装配的所有配置类,读取META-INF/spring.factories;configurations就是所有META-INF/spring.factories下XXXAutoConfiguration类
//不光是这个依赖下的META-INF/spring.factories被读取到,所有 Spring Boot Starter 下的META-INF/spring.factories都会被读取到。
List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
configurations = removeDuplicates(configurations);
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
//@ConditionalOnXXX 中的所有条件都满足,该类才会生效。
configurations = filter(configurations, autoConfigurationMetadata);
fireAutoConfigurationImportEvents(configurations, exclusions);
return new AutoConfigurationEntry(configurations, exclusions);
}
以上是SpringBoot自动装配的基本流程;
核心处理@Configuration部分如下:
1、创建context的时候加载 ConfigurationClassPostProcessor
2、prepared context的 load 加载主函数到bean定义中
3、refreshContext方法 invokeBeanFactoryPostProcessors 调用ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry方法
4、主类带有@Configuration doProcessConfigurationClass 进行处理这时候会加载imports注解中的类
接着处理imports导入的类,在AutoConfigurationImportSelector中 利用loadFactory spi技术加载EnableAutoConfiguration对应的类
本文深入解析了SpringBoot的@SpringBootApplication注解,它是@Configuration、@EnableAutoConfiguration和@ComponentScan的组合。@EnableAutoConfiguration启动自动配置机制,@Configuration允许添加额外的bean,@ComponentScan扫描@Component等注解的bean。在AutoConfigurationImportSelector类中,通过ImportSelector接口的selectImports方法获取并加载符合条件的自动配置类。整个过程涉及SpringFactoriesLoader加载META-INF/spring.factories中的配置。自动配置的核心在于根据条件判断哪些配置类生效。
978

被折叠的 条评论
为什么被折叠?



