这是我参与11月更文挑战的第10天,活动详情查看:2021最后一次更文挑战
前言
一般Spring Boot应用的启动类都位于 src/main/java
根路径下
其中 @SpringBootApplication
开启组件扫描和自动配置,而 SpringApplication.run
则负责启动引导应用程序。
注解@SpringBootApplication
@SpringBootApplication
是一个复合 Annotation
,它将三个有用的注解组合在一起:
2.1. @SpringBootConfiguration
@SpringBootConfiguration
就是 @Configuration
,它是Spring框架的注解,标明该类是一个 JavaConfig
配置类。而 @ComponentScan
启用组件扫描,前文已经详细讲解过,这里着重关注 @EnableAutoConfiguration
。
2.2. @EnableAutoConfiguration
@EnableAutoConfiguration
注解表示开启Spring Boot自动配置功能,Spring Boot会根据应用的依赖、自定义的bean、classpath下有没有某个类 等等因素来猜测你需要的bean,然后注册到IOC容器中。
2.2.1 @EnableAutoConfiguration 定义
Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
/**
* Environment property that can be used to override when auto-configuration is
* enabled.
*/
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 {};
}
@Import(EnableAutoConfigurationImportSelector.class)
是重点。
2.2.2 EnableAutoConfigurationImportSelector
@Import
注解用于导入类,并将这个类作为一个bean的定义注册到容器中,这里它将把 EnableAutoConfigurationImportSelector
作为bean注入到容器中,而这个类会将所有符合条件的@Configuration配置都加载到容器中
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return NO_IMPORTS;
}
AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
这个类会扫描所有的jar包,将所有符合条件的@Configuration配置类注入的容器中,何为符合条件,看看 META-INF/spring.factories
的文件内容:
我们看下SPringBoot启动类里面的内容,org.springframework.boot.autoconfigure下的META-INF/spring.factories
比如我们前面介绍的flyway数据库配置管理工具。
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
EnableAutoConfigurationImportSelector#selectImports方法何时执行?
在容器启动过程中执行: AbstractApplicationContext#refresh()方法