一、原理
@SpringBootApplication 注解通常放置在主启动类上,这个类也是应用程序的入口点。
Spring Boot 应用启动时,会读取这个注解,并根据其配置来设置 Spring 应用上下文。
@SpringBootApplication 是 Spring Boot 应用中最常用的注解,它是一个组合注解。
进入 @SpringBootApplication 注解。
-
@EnableAutoConfiguration 开启 Spring Boot 的自动配置功能,根据类路径中的 jar 依赖和其他条件,自动配置 Spring 应用。
-
@ComponentScan 指示 Spring 在注解所在类的包及其子包中搜索标注了 @Component 及其变体(如@Service、@Repository、@Controller)的类,并将它们注册为 Spring 容器中的beans。
-
@SpringBootConfiguration 标注在某个类上,表示这是一个SpringBoot的配置类。
进入 @EnableAutoConfiguration 注解。
@Import({AutoConfigurationImportSelector.class}):给容器导入组件。
AutoConfigurationImportSelector:自动配置导入选择器,给容器中导入一些组件。
AutoConfigurationImportSelector 是一个实现了 ImportSelector 接口的类,当 Spring 解析到带有@Import 注解的类时,它会调用 AutoConfigurationImportSelector的 selectImports 方法。
进入 AutoConfigurationImportSelector 类。
在 selectImports 方法中找到 this.getAutoConfigurationEntry(annotationMetadata) 方法。
在 this.getAutoConfigurationEntry(annotationMetadata) 方法中找到
this.getCandidateConfigurations(annotationMetadata, attributes) 方法。
进入 this.getCandidateConfigurations(annotationMetadata, attributes) 方法,该方法方法体为:
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.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;
}
loadFactoryNames
方法查找 META-INF/spring.factories
文件中指定键下的值。
对于 AutoConfigurationImportSelector
,键是 "
org.springframework.boot.autoconfigure.EnableAutoConfiguration
"
,对应的值就是一系列自动配置类的全限定名。
这些类都是 Spring Boot 自动配置机制中的一部分,它们代表了 Spring Boot 在启动时根据不同的场景和依赖自动配置的组件。这些类通常以 AutoConfiguration 结尾,它们是 Spring Boot 自动配置的“大脑”,负责分析类路径、环境和应用需求,为应用添加合适的配置。
AutoConfigurationImportSelector类中流程可概括如下:
AutoConfigurationImportSelector.class
↓
selectImports方法
↓
this.getAutoConfigurationEntry(annotationMetadata)方法
↓
this.getCandidateConfigurations(annotationMetadata, attributes)方法
↓
方法体:
List<String> configurations =
SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass
(), this.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;
↓
在所有包名叫做autoConfiguration的包下面都有META-INF/spring.factories文件
小总结:
-
@EnableAutoConfiguration 注解内部使用 @Import(AutoConfigurationImportSelector.class) 来加载配置类。
-
配置文件位置:META-INF/spring.factories,该配置文件中定义了大量的配置类,当 Spring Boot 应用启动时,会自动加载这些配置类,初始化Bean。
-
并不是所有的Bean都会被初始化,在配置类中使用 Condition 来加载满足条件的Bean。
二、两个注解
有兴趣的话可以再了解一下下面的两个注解,有助于理解 Spring Boot 自动配置原理。
1.Condition
Condition 是在Spring 4.0 增加的条件判断功能,通过这个可以功能可以实现选择性的创建 Bean 操作。它允许开发者根据特定的条件来决定是否注册一个配置类或创建一个 bean。
Spring Boot 提供的常用条件注解:
以下注解在springBoot-autoconfigure的condition包下。
-
ConditionalOnProperty:判断配置文件中是否有对应属性和值才初始化Bean。
-
ConditionalOnClass:判断环境中是否有对应字节码文件才初始化Bean。
-
ConditionalOnMissingBean:判断环境中没有对应Bean才初始化Bean。
-
ConditionalOnBean:判断环境中有对应Bean才初始化Bean。
例如:
2.@Enable注解
Spring Boot 中提供了很多 Enable 开头的注解,这些注解都是用于动态启用某些功能的。而其底层原理是使用 @Import 注解导入一些配置类,实现Bean的动态加载。
@Enable 底层依赖于 @Import 注解导入一些类,使用 @Import 导入的类会被 Spring 加载到 IOC容器中。
而 @Import 提供4中用法:
① 导入Bean。
② 导入配置类。
③ 导入 ImportSelector 实现类。一般用于加载配置文件中的类。
④ 导入 ImportBeanDefinitionRegistrar 实现类。