【十九】Spring IOC 总结之启动时定位资源和BeanDefinition载入、解析、注册(SpringBoot 扫启动类所在包、starter、@Import)

源码调试以spring boot 1.5.8.release为例

Spring IOC容器初始化主要有以下几个步骤

1、资源定位:找到配置文件。

2、BeanDefinition载入和解析

3、BeanDefinition注册

4、实例化bean和依赖注入  (不在本篇讨论范围,该内容总结请看【十八】Spring IOC 总结之getBean主流程和各个扩展点总结

而这一系列的操作种的前三步在SpringBoot中都是在AbstractApplicationContext#invokeBeanFactoryPostProcessors方法中完成的,该方法的源码导读请看以前写的这篇:【四】Spring源码分析之启动主流程---AbstractApplicationContext的refresh方法  只是对该方法做了一个简单介绍而已。

这个invokeBeanFactoryPostProcessors方法写的很恶心,里面是调用了ConfigurationClassPostProcessor的processConfigBeanDefinitions方法真正完成的资源定位、BeanDefinition载入和解析、BeanDefinition注册,该方法源码导读请看以前写的这篇:【八】Spring源码分析之扫描注册Bean----ConfigurationClassPostProcessor的processConfigBeanDefinitions方法

本篇主要是总结一下SpringBoot怎么做定位资源,主要的3中定位资源的方式

这里涉及到常规的Spring Boot项目中有3种定位方式:

1.扫主类(就是有注解@SpringBootApplication这个类)所在包的路径

2.SPI扩展机制实现的自动装配(比如各种starter)

3.@Import注解指定的类。

 上面已经提到入口是ConfigurationClassPostProcessor的processConfigBeanDefinitions

这里面是调用ConfigurationClassParser#parse(Set<BeanDefinitionHolder> configCandidates)方法来做的定位

该方法中主要是两个事:

1.继续调用本类的其他parse方法做定位,最终的逻辑是在doProcessConfigurationClass方法中。

该方法包含了两种定位资源的方式
扫描springboot的有@SpringBootApplication注解的那个启动类所在的路径和对启动类的@Import注解的处理

2.processDeferredImportSelectors方法加载默认的配置(对springboot项目来说这里就是自动装配的入口了)

一、ConfigurationClassParser#doProcessConfigurationClass方法

该方法就是扫描springboot的有@SpringBootApplication注解的那个启动类所在的路径

1.首先递归处理启动类的内部类,我们一般不会在启动类写内部类,就不debug这个了

2.对 @PropertySource 注解的属性配置进行处理,这个我也没有触发到

解析该注解并将该注解指定的properties配置文件中的值存储到Spring的 Environment中,Environment接口提供方法去读取配置文件中的值,参数是properties文件中定义的key值。

3.对 @ComponentScan 注解进行处理(该注解在@SpringBootApplication注解中)

1.扫描启动类所在的包,找到所有的@Component注解修饰的bean,并注册到BeanDefinitionMap中

这里就是从basePackage中扫描类并解析成ScannedGenericBeanDefinition然后注册

主要逻辑的实现入口在ClassPathBeanDefinitionScanner#doScan

2.检查该bean是否是ConfigurationClass(是否有configuration/component两个注解)

如果是,递归查找该类相关联的配置类。

(相关的配置类:比如@Configuration中的@Bean定义的bean。或者在有@Component注解的类上继续存在@Import注解)

4.递归处理启动类中的@Import,并加载该注解指定的配置类。

这里说一下,@SpringBootApplication注解中包含@EnableAutoConfiguration注解,

而@EnableAutoConfiguration注解

包含@Import(EnableAutoConfigurationImportSelector.class)和@AutoConfigurationPackage这两个注解是重点

5.处理启动类中的@ImportResource注解,这里没有触发

6.处理启动类中的@Bean注解,这里没有触发

7.处理启动类实现的接口方法,并没有触发

8.处理启动类的父类,并没有触发

二、processDeferredImportSelectors方法加载默认的配置

该方法就是通过启动类的@Import加载各个jar下META-INF/spring.factories的自动配置类并注册

对springboot项目来说这里就是自动装配的入口了

1.该方法里面会调用EnableAutoConfigurationImportSelector的父类AutoConfigurationImportSelector的selectImports方法

1.获取所有的自动配置类(META-INF/spring.factories中配置的key为org.springframework.boot.autoconfigure.EnableAutoConfiguration的类)

2.排除的自动装配类(springboot的主类上 @SpringBootApplication(exclude = {com.demo.starter.config.DemoConfig.class})指定的排除的自动装配类)

3.过滤掉不需要装配的类。过滤的逻辑有很多,比如我们常用的@ConditionXXX注解

4.返回需要自动配置类的全名

2.然后用ConfigurationClassParser#doProcessConfigurationClass方法讲这些自动配置类加载并注册

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值