概要
何为自动装配?自动装配可简单理解为Spring自动读取配置类信息,并解析配置类中的Bean信息,然后将相关Bean初始化到IOC容器中。前面两个章节已经了解了SPI技术和Spring中Import注解的实现原理,本章节来具体讲解Spring boot如何使用通过EnableAutoConfiguration注解将Bean自动注入到Spring容器中。
源码剖析
Spring Boot将相关配置都集成到了SpringBootApplication注解,在启动类加上该注解则标识为Spring Boot应用,进入SpringBootApplication类可以看到该类集成了@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan三个注解,SpringBootConfiguration继承了@Configuration,标识该类为Spring的配置类,在Spring启动IOC容器的时候可以识别并解析,ComponentScan表示IOC容器启动时,需要去扫描注册的Spring组件,EnableAutoConfiguration即标识开启Spring Boot 自动配置,进入之后发现其主要包含了两个注解,一个为AutoConfigurationPackage,另一个为Import,AutoConfigurationPackage默认没有扫描的包路径暂忽略,Import注解导入了AutoConfigurationImportSelector,该类为Spring Boot自动装配核心类,通过该类自动装载了Spring Boot需要的对象到IOC,下面对该类进行重点讲解。
首先上源码
AutoConfigurationImportSelector
由于AutoConfigurationImportSelector实现了DeferredImportSelector(延迟导入)接口,其自动装配会经过ConfigurationClassParser进行后置处理(this.deferredImportSelectorHandler.process(),通过ConfigurationClassParser$DeferredImportSelectorHandler#process方法处理)。
DeferredImportSelector与ImportSelector导入选择器有所不同,DeferredImportSelector会对导入选择器进行分组DeferredImportSelector$Group(即不能的选择器分配到不同的组),然后调用分组内部方法process(DeferredImportSelector$Group#process)解析META-INF/spring.factories路径所有标注key为org.springframework.boot.autoconfigure.EnableAutoConfiguration的配置类,并将其存储在
autoConfigurationEntries和entries集合中,再通过调用分组内部方法selectImports(DeferredImportSelector$Group#selectImports)返回需要进行自动装配的配置类实体集合,之后交给ConfigurationClassParser#processImports进行解析。
ImportSelector是直接调用ImportSelector#selectImports方法,获取需要自动装配的配置类classname集合,之后交给ConfigurationClassParser#processImports进行解析。
总结:
Spring Boot自动装配的流程是先通过SpringApplication将@SpringApplication注解类注入到Spring IOC容器,然后通过ConfigurationClassParser对标注@Configuration的类进行解析,当解析到@EnableAutoConfiguration注解的时候,发现其内部通过Import注解导入了AutoConfigurationImportSelector类,ConfigurationClassParser通过processImports方法去解析AutoConfigurationImportSelector。AutoConfigurationImportSelector通过selectImports方法运用SPI机制获取Spring Boot所有jar包内META-INF/spring.factories文件内路径标注key为org.springframework.boot.autoconfigure.EnableAutoConfiguration的配置类,然后通过一些列的excludeFilter排除相关配置类,获取到相关配置类之后,交由ConfigurationClassParser解析出来,并存入Spring IOC容器对应BeanFactory的beanDefinitionMap中,最终通过DefaultListableBeanFactory#preInstantiateSingletons进行实例化,该过程就将Spring Boot的一些Bean自动注入到了Spring IOC容器中。