众所周知,springboot的出现为开发带来了很大的方便,主要就是提供了很多自动配置,免去了开发人员花在配置上的时间,使我们开发者能更专注于业务或者架构设计上。
而springboot的自动配置是通过一系列注解来完成的,例如@EnableAutoConfiguration
、@Conditional
、@ConditionalOn*
、@EnableConfigurationProperties
等等。
这一系列注解我觉得大致可分为两类,一类是条件注解,一类是与配置相关的注解,下面分别举一些例子进行说明。
条件注解
@ConditionalOnBean
当容器里有指定的bean类或者名称时,满足匹配条件
@ConditionalOnMissingBean
当容器里缺少指定的bean类或者名称时,满足匹配条件
@ConditionalOnProperty
检查指定的属性是否有特定的值,name为指定值的key,havingValue为指定值,matchIfMissing为缺少或为设置值时,是否也进行匹配
@ConditionOnClass
当有指定类在classpath时,满足匹配条件
@ConditionOnMissClass
当指定类在classpath不存在时,满足匹配条件
配置相关注解
@EnableAutoConfiguration
开启自动配置
@AutoConfigureAfter
在指定的自动配置类之后进行配置
@AutoConfigureBefore
在指定的自动配置类之前进行配置
@EnableConfigurationProperties
开启对
@ConfigurationProperties
修饰的bean的支持,将@ConfigurationProperties
修饰的类注册成bean
而最核心的我想就是@EnableAutoConfiguration
注解了,毕竟只有有了它才能开启自动配置,是所有自动配置的起点,那么就从它开始探索下自动配置的原理。
以下源码版本为springboot 2.0.5.RELEASE
先看下这个注解:
1 | (ElementType.TYPE) |
可以看到这里导入了AutoConfigurationImportSelector
,先看下该类核心的selectImports()
方法:
1 |
|
可以看出,先获取到所有配置,然后删除重复的配置,然后获取需要排除的配置类,再检查需要排除的配置类,从所有配置中移除需要排除的配置,再使用filter过滤掉不满足自动导入条件的配置(例如使用了@Contional
及衍生的条件注解的配置类),最后将剩下的配置类返回。
下面我们具体地看下selectImports()
中的getCandidateConfigurations()
:
1 | protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, |
该方法主要通过SpringFactoriesLoader.loadFactorynames()
使用当前的类加载器返回指定EnableAutoConfiguration
在META-INF/spring.factories
对应的所有配置类名。
那么META-INF/spring.factories
是什么呢,在spring-boot-autoconfigure.jar包下有这样一个文件:
1 | # Auto Configure |
可以看到,这里几乎写了所有springboot提供的各种配置类,所以@EnableAutoConfiguration
导入了AutoConfigurationImportSelector
,就几乎相当于将所有的配置类都引入进来加载了,所以springboot的自动配置换句话说,其实是帮我们定义了很多通用配置的配置类,再统一按条件引入进来加载。
至于selectImports()
中其他作用的实现都比较简单,值得一看的是通过filter(configurations, autoConfigurationMetadata)
过滤不满足条件的配置类,源码:
1 | private List<String> filter(List<String> configurations, |
这里主要是从META-INF/spring.factories
中获取到AutoConfigurationImportFilter
:
1 | # Auto Configuration Import Filters |
即OnClassCondition
,调用match()
方法检查是否存在有@ConditionalOnClass
和@ContionalOnMissClass
注解的配置类。
至此,关于@EnableAutoConfiguration
的自动配置原理我们心里也有了答案。