一,什么是SpringBoot的自动配置
Spring Boot通过@EnableAutoConfiguration注解开启自动配置,对jar包下的spring.factories文件进行扫描,这个文件中包含了可以进行自动配置的类,当这些类满足指定的条件时,会注册到Spring容器中。
二,自动配置原理
1.@SpringBootApplication
在启动类上方使用了@SpringBootApplication注解,我们点击进入。
2.@SpringBootConfiguration,@EnableAutoConfiguration,@ComponentScan
其中关键的部分是@SpringBootConfiguration,@EnableAutoConfiguration,@ComponentScan三个注解。
@SpringBootConfiguration:继承自Configuration,支持JavaConfig的方式进行配置。
@EnableAutoConfiguration:下文重点讲解,用于开启自动配置。
@ComponentScan:自动扫描组件,默认扫描该类所在包及其子包下所有带有指定注解的类,将它们自动装配到bean容器中,会被自动装配的注解例如@Controller、@Service、@Component、@Repository等。也可以指定扫描路径。
3.@SpringBootConfiguration
4.@EnableAutoConfiguration
点击进来发现,看到@AutoConfigurationPackage和导入了一个类。
@AutoConfigurationPackage 自动包规则原理
主启动类(加上@SpringBootApplication注解的类),找到它的包名,扫描当前包下所有带有注解的bean,注册至IOC容器中。
然后引入了AutoConfigurationImportSelector.class,我们点击进入。
5.AutoConfigurationImportSelector
发现AutoConfigurationImportSelector最终继承自ImportSelector。并且重写了
String[] selectImports,阅读发现,首先判断是否开启自动配置,然后进入getAutoConfigurationEntry方法。
关键的是getCandidateConfigurations,之前是加载自动配置的元信息,之后是对候选配置进行过滤,我们点击进入。
6.SpringFactoriesLoader
spring-core包里定义了SpringFactoriesLoader类,这个类实现了检索META-INF/spring.factories文件,并获取指定接口的配置的功能。在这个类中定义了两个对外的方法:
loadFactories 根据接口类获取其实现类的实例,这个方法返回的是对象列表。
loadFactoryNames 根据接口获取其接口类的名称,这个方法返回的是类名的列表。
点击loadFactoryNames。
发现最终是读取了META-INF/spring.factories文件。
6.spring.factories和xxx.imports
然后就是加载spring.factories文件和xxx.imports文件中的类,将其加入Spring容器中进行自动配置。
7.例子
在imports文件中点击Redis的自动配置
由于我们没有引入Redis的依赖,因此@ConfitionalOnClass并不会加载此配置类,所以SpringBoot并不是引入所有的配置,而是会经过过滤。
如果我们引入了Redis的依赖,那么就会读取RedisProperties.class中的配置项,将其默认值与配置属性绑定,实现自动配置。
三,总结
在主启动类上添加了SpringBootApplication注解,这个注解组合了EnableAutoConfiguration注解。EnableAutoConfiguration注解又组合了lmport注解,导入了又组合了lmport注解,导入了又组合了lmport注解,导入了AutoConfigurationlmportSelector类,实现selectlmports方法,这个方法经过层层调用,最终会读取META-INF目录下的后缀名为imorts的文件,当然了, boot2.7以前的版本,读取的是spring.factories文件,读取到全类名了之后,会解析注册条件,也就是@Conditional及其衍生注解,把满足注册条件的Bean对象自动注入到loc容器中。