自动配置原理
自动配置原理
Auto-Configuration
- 它是基于你引入的依赖jar包,对SpringBoot应用进行自动配置
- 他为SpringBoot框架的“开箱即用”提供了基础支撑
术语“配置类”,英文Configuration Class
:
- 广义的“配置类”:被注解
@Component
直接或间接修饰的某个类,即我们常说的Spring
组件,其中包括了@Configuration
类 - 狭义的“配置类”:特指被注解
@Configuration
所修饰的某个类,又称为@Configuration
类
相关注解
@ComponentScan
@ComponentScan
,是来自Spring
框架的一个注解:
- 它的作用对指定的
package
进行扫描,找到其中复合条件的类,默认是搜索被注解@Component
修饰的配置类 - 通过属性
basePackages
或basePackageClasses
,来指定要进行扫描的package
- 如果未指定
package
,则默认扫描当前@ComponentScan
所修饰的类所在的package
@Import
是来自Spring
框架的一个注解:
- 它的作用是提供了一种显示地从其他地方加载配置类的方法,这样可以避免使用性能较差的组件扫描(
ComponentScan
) - 支持导入:
- 普通类(这里的普通,是相对随后的两个接口而言的)
- 接口ImportSelector的实现类
- 接口ImportBeanDefinitionRegistrar的实现类
@SpringBootApplication
@SpringBootConfiguration
@Configuration
@EnableAutoConfiguration
@Import(AutoConfigurationImportSelector.class)
@ComponentScan
@SpringBootApplication
修饰的类,也会被@Configuration
简介修饰,即“原配置类”
SpringBoot
框架会对“原配置类”所在的package进行组件扫描(ComponentScan
)
SpringBoot
框架最终会导入AutoConfigurationImportSelector
来实现自动配置
@Conditional
- 它的作用是实现:只有在特点条件满足时,才会向
IoC
容器注册指定的组件 - 我们可以将
@Conditional
理解为某种IF
语句
常用:
注解名称 | 作用 |
---|---|
ConditionalOnBean | 当容器存在指定的Bean时,满足条件 |
ConditionalOnMissingBean | 当容器不存在指定的Bean时,满足条件 |
ConditionalOnClass | 当classpath中存在指定的类时,满足条件 |
ConditionalOnMissingClass | 当classpath中不存在指定的类时,满足条件 |
自动配置类实例
Redis的自动配置
- 引入依赖
- 配置Redis服务器
- 直接使用
RedisTemplate
或StringRedisTemplate
1 |
|
SpringBoot的启动流程(简化版)
简化版代码
1 | public static void run(Class<?> primaryClass){ |
加载并处理所有的配置类processConfigurationClasses()
1 | public static void processConfigurationClasses(ApplicationContext context){ |
递归函数parse
1 | public void parse(Class<?> configClass){ |
如何实现类AutoConfigurationImportSelector
SpringFactories机制
Java SPI
机制的延伸和扩展Spring
框架的基础机制,在Spring
以及SpringBoot
源码中到处可见- 可以基于它来实现
SpringBoot
的自动配置功能
核心逻辑
从classpath
中读取到所有jar包中的配置文件META-INF/spring.factories
,然后根据指定的key
从配置为念中解析出对应的value
值
SpringBoot
在启动时会扫描外部引用jar包中的META-INF/spring.factories
文件,将文件中的配置类型信息加载到Spring
容器,并执行类中定义的各种操作
EnableAutoConfiguration
,是实现自动装配的重要注解。内部的实际实现是AutoConfigurationImportSelector
类来实现,getAutoConfigurationEntry
可以返回需要导入的自定义配置,将这些类加载到IOC
容器中
在获取的导入配置中,首先会扫描所有的自动配置类,接着根据自定义配置中的ConditionalOnXXX
注解做判断,决定是否将其放入最终的导入集合中
例如:
@ConditionalOnBean
@ConditionalOnClass
@ConditionalOnProperty
具体步骤:
- 通过
@SpringBootConfiguration
引入@EnableAutoConfiguration
(负责启动自动配置功能) @EnableAutoConfiguration
引入了@Import
Spring
容器启动时:加载IOC容器会解析@Import
注解@Import
导入了一个deferredImportSelector
,它会使Spring的自动配置类的顺序在最后,这样方便我们扩展和覆盖- 然后读取所有的
/META-INF/spring.factories
文件 - 筛选出所有以
EnableAutoConfiguration.class
为key
的、符合条件的配置类,过滤出所有AutoConfigurationClass
类型的类 - 最后通过
@ConditionOnXXX
排除无效的自动配置类
一句话总结,自动配置就是通过扫描jar
包下面/META-INF/Spring.factories
获取到自动配置,再根据@Conditional
按需加载的配置类