源码分析——spring生命周期(上)

@源码分析——spring生命周期(上)

基本概念解释

1、spring容器:AnnotationConfigApplicationContext spring容器等于
BeanDefinitionRegistry 注册器等于
DefaultListableBeanFactory spring bean工厂
2、BeanDefinition java类交给spring容器管理的数据结构 ,包含了类的其他信息,比如一些元信息,scope,lazy等等 ,文中简称bd
3、beanDefinitionMap java类和bd的键值对,是DefaultListableBeanFactory的一个属性
4、beanDefinitionNames bd名称的集合,也是DefaultListableBeanFactory的一个属性
5、DefaultListableBeanFactory 里面包含了 Map<String, BeanDefinition> beanDefinitionMap
List beanDefinitionNames 等
6、BeanDefinitionHolder 也是一种数据结构,包含BeanDefinition,beanName等
7、BeanFactoryPostProcessor spring工厂后置处理器,是对DefaultListableBeanFactory的延伸
8、BeanPostProcessor 是Spring框架的提供的一个扩展类点,也就是bean的后置处理器,
通过实现BeanPostProcessor接口,我们就可插手bean实例化的过程,
从而减轻了beanFactory的负担,
比如AOP就是在bean实例后期间将切面逻辑织入bean实例中的,
AOP也正是通过BeanPostProcessor和IOC容器建立起了联系
9、由于spring源码层级机构太复杂,本文用–>表示方法向下渗透
10、对插图进行编号,如“图一”,便于行文时进行定位

spring容器结构

在这里插入图片描述

spring容器初始化过程

图一在这里插入图片描述
图二**
在这里插入图片描述
图三
在这里插入图片描述本文基于java config方式进行阐述
图三第一行super();
AnnotationConfigApplicationContext 初始化容器的时候会调用父类构造方法 初始化了 spring默认工厂DefaultListableBeanFactory

图三第二行初始化了bd读取器
–>
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
this(registry, getOrCreateEnvironment(registry));
}

这里的BeanDefinitionRegistry registry是通过在AnnotationConfigApplicationContext的构造方法中传进来的this,由此说明AnnotationConfigApplicationContext是一个BeanDefinitionRegistry类型的类

类继承关系
AnnotationConfigApplicationContext extends GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry

–>AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);

—>
图四
在这里插入图片描述
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);首先这句话印证了文中的话BeanDefinitionRegistry 等于DefaultListableBeanFactory 的话,
DefaultListableBeanFactory 是BeanDefinitionRegistry 的一个实现类

可以看到这里注册了各种工厂后置处理器,这里重点说一下ConfigurationClassPostProcessor
(这个ConfigurationClassPostProcessor后文会提到)
这个方法里面注册了各种工厂后置处理器,继承或者实现关系
ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor
所谓注册 比如registerPostProcessor方法 其实就是把bd放进DefaultListableBeanFactory中,
通过beanDefinitionMap 结构存储, key为bean的名称,value为bd,
且这个bd:
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class))
是通过构造方法把ConfigurationClassPostProcessor工厂后置处理器封装起来的

图二第二行register方法 注册AnnotatedGenericBeanDefinition
它也是bd的一种,类的作用域,Lazy DependsOn Primary Role等等注解,然后封装到BeanDefinitionHolder

扫描二维码关注公众号,回复: 9812747 查看本文章

图二第三行refresh方法

图五

在这里插入图片描述
本文重点阐述
prepareBeanFactory(beanFactory);
invokeBeanFactoryPostProcessors(beanFactory);
–>
图六
在这里插入图片描述

图六中加入可以看到prepareBeanFactory方法加入了各种bean的后置处理器,就可以插手bean的实例化过程,里面实现了BeanPostProcessor 的两个方法:postProcessBeforeInitialization,postProcessAfterInitialization
顾名思义就是bean实例化前置处理和后置处理,
其中ApplicationContextAwareProcessor的postProcessBeforeInitialization中调用了invokeAwareInterfaces方法,里面有一段核心代码:
//spring帮你set一个applicationContext对象
//所以当我们自己的一个对象实现了ApplicationContextAware对象只需要提供setter就能得到applicationContext对象
if (bean instanceof ApplicationContextAware) {
System.out.println(bean.getClass().getSimpleName());
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}

图七
在这里插入图片描述
图八
在这里插入图片描述
图七,图八为invokeBeanFactoryPostProcessors方法重点代码
invokeBeanFactoryPostProcessors主要是在spring的beanFactory初始化的过程中去做一些事情,怎么来做这些事情呢?
委托了多个实现了BeanDefinitionRegistryPostProcessor或者BeanFactoryProcessor接口的类(BeanDefinitionRegistryPostProcessor 是对BeanFactoryProcessor的拓展) 来做这些事情,有自定义的也有spring内部的,其中ConfigurationClassPostProcessor就是一个spring内部的BeanDefinitionRegistryPostProcessor
这里说一下ConfigurationClassPostProcessor,如图八
这个地方可以得到一个BeanFactoryPostProcessor,因为是spring默认在最开始自己注册的(上文中实例化读取器的时候),为什么要在最开始注册这个呢?
因为spring的工厂需要许解析去扫描等等功能,而这些功能都是需要在spring工厂初始化完成之前执行,要么在工厂最开始的时候、要么在工厂初始化之中,反正不能再之后,因为如果在之后就没有意义,因为那个时候已经需要使用工厂了,所以这里spring’在一开始就注册了一个BeanFactoryPostProcessor,用来插手springfactory的实例化过程,在这个地方断点可以知道
这个类叫做ConfigurationClassPostProcessor

图九
在这里插入图片描述
图十

在这里插入图片描述
图十一
在这里插入图片描述
上文说了实现BeanDefinitionRegistryPostProcessor,BeanFactoryProcessor可以是自定义的也可以是spring内部的

图九、图十、图十一
这里验证了一下自定义的工厂后置处理器,图九中做了一下改变,在refresh之前,也就是工厂初始化之前,就加上自定义的工厂后置处理器MyBeanFactoryPostProcessor,在图十一中断点处可以看到getBeanFactoryPostProcessors方法,这个方法就是来获取自定义的工厂后置处理器。注意到图十,是去掉了@Component注解的,因为如果加了,getBeanFactoryPostProcessors()这个地方是得不到的,而是spring自己扫描。
到这里为止,容器的初始化就基本完成了,这里的invokeBeanFactoryPostProcessors方法其实很重要,这里的细节很多,由于篇幅有限放在中篇或者附加篇中再单独阐述。
spring生命周期的接下来流程敬请期待中篇!

发布了1 篇原创文章 · 获赞 4 · 访问量 103

猜你喜欢

转载自blog.csdn.net/qq_32387579/article/details/104814200