前言
springboot 大幅简化了 spring 框架的繁琐配置,非常容易快速上手。一个简单的 springboot 应用,只要加上@SpringBootApplication 注解就可以实现自动配置。而对于许多第三方库,只要引入相应的 starter,就可以直接生成相应的 bean 而无需自行初始化。而这就是 springboot 的自动装配机制。
那么自动装配机制是如何实现的呢?今天我们就来探究一下。
导航
@EnableAutoConfiguration 注解
@SpringBootApplication 注解集合了@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan 三大注解,自动装配无疑和@EnableAutoConfiguration 注解有关。
1 |
|
可以看到@EnableAutoConfiguration 注解使用@Import 导入了两个类,分别是 AutoConfigurationPackages.Registrar 和 AutoConfigurationImportSelector。
先来看@Import 注解。调用关系是这样的:
1 | ->context.refresh() |
这里的 postProcessors 包括 ConfigurationClassPostProcessor,将会调用其的 postProcessBeanDefinitionRegistry()方法,这个方法会加载注册更多的 bean 定义信息, 主要是通过 ConfigurationClassParser 的 parse()方法和 ConfigurationClassBeanDefinitionReader 的 loadBeanDefinitions()。
其中各种注解的解析在 parse()中,包括@PropertySource、@ComponentScan、@Import、@ImportResource、@Bean 等。注意,@import 注解就在其中:
1 | // Process any @Import annotations |
由此可见,processImports()方法就是@Import 的处理逻辑,点开它:
1 | // ... |
由于 AutoConfigurationImportSelector 继承的是 ImportSelector 的子接口 DeferredImportSelector,所以在这里它并不会直接调用 selectImports 方法,而是通过 handler 获取其静态内部类 AutoConfigurationGroup,执行内部类的 process()和 selectImports()方法,其中 process()就会扫描 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 里的 class,注意自 3.0 版本的路径不再是 META-INF/spring.factories 了。
@Conditional
打开 starter,经常发现配置类上有各种 Conditional 注解,如@ConditionalOnBean、@ConditionalOnClass、@ConditionalOnProperty 等等,那么这些注解是怎么起作用的呢?追踪源码发现,依然是在 ConfigurationClassParser 的 doProcessConfigurationClass()方法中:
1 | if (!componentScans.isEmpty() && |