8、Springboot 自动配置原理
大约 2 分钟
8、Springboot 自动配置原理
1.简介
Springboot 的自动配置原理,是 Springboot 中最高频的一道面试题,也是 Springboot 框架最核心的思想。
首先我们看一张我总结的自动配置原理概览图:
下面,我们就根据这张图详细描述一下具体过程:
2.@SpringBootApplication 注解
首先,我们来看一段代码:
@SpringBootApplication
public class SpringbootDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootDemoApplication.class, args);
}
}
上面就是一段普通的 Springboot 引导类代码,这里有一个非常关键的注解 @SpringBootApplication
,其实 Springboot 的自动配置主要就是依赖这个注解,这个注解还包含了另外三个注解:
3.三大注解
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
}
- @SpringBootConfiguration:该注解与 @Configuration 注解作用相同,用来声明当前也是一个配置类。
- @EnableAutoConfiguration:SpringBoot 实现自动化配置的 核心注解。
- @ComponentScan:组件扫描,默认扫描当前引导类所在包及其子包。
接下来我们就主要看一下 @EnableAutoConfiguration
注解:
4.@EnableAutoConfiguration 注解
@EnableAutoConfiguration 注解的部分源码如下:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
}
其中核心的代码为 @Import
注解中指定的 AutoConfigurationImportSelector.class
类。
@Import
注解的作用是导入某些类,然后注入到 Spring 容器中。
AutoConfigurationImportSelector.class
类是我们需要自动导入的自动配置的选择器。
这里还会去加载 spring.factories
配置文件,将文件中的类都注入到 Spring 容器中。
5.spring.factories
spring.factories
文件内容大致如下,其中很多类是以 AutoConfiguration 结尾的:
(注意:这里面的类并不是会全部注入到容器中的,会根据 @ConditionalOnClass
注解值选择性注入)
比如我们打开其中的 RedisAutoConfiguration
类:
6.示例:RedisAutoConfiguration 类
- @Configuration:标识当前类为配置类。
- @ConditionalOnClass:判断是否有对应的字节码,字节码存在时才将当前 Bean 注入到容器中。
- @EnableConfigurationProperties:用于启用 @ConfigurationProperties 注解的自动绑定功能,可以获取配置文件中的属性值。
- @Bean:用于将方法的返回值 Bean 注入到 Spring 容器中。
- @ConditionalOnMissingBean:判断环境中是否不存在对应的 Bean,如果不存在则创建当前 Bean 并注入到 Spring 容器中。
- @ConditionalOnSingleCandidate:用于标识只有在容器中存在单个候选 Bean 时才创建按当前 Bean 并注入到 Spring 容器中。
整理完毕,完结撒花~ 🌻