IOC容器启动及Bean生成流程
目录
一、容器启动
-
IOC启动流程
-
重点
二、扫描并注册BeanDefination
-
加载并过滤资源
-
注册BeanDefination
三、BeanFactory后置处理
四、注册Bean后置处理器
五、遍历BeanDefination,实例化单例Bean
-
preInstantiateSingletons
-
doGetBean(我们只关注单例)
-
createBean
- 实例化前执行
-
doCreateBean
-
实例化
-
属性赋值
-
初始化
-
-
getSingleton
六、总结
没有很详细了解Bean的可能只知道Bean会经历实例化,初始化,属性赋值这些所谓的Bean生命周期,再往下细聊可能就不清楚了,这次呢我们就全面的了解一下IOC容器的启动流程,然后重点看一下其中有关Bean的流程!
一、容器启动
上节我们说过了,容器启动入口就是ApplicationContext,有两个重要的实现类:
-
AnnotationConfigApplicationContext: 基于注解包路径扫描的容器上下文,通过扫描注解来完成BeanDefinition的注册
-
ClassPathXmlApplicationContext: 基于类路径下xml文件的Spring应用程序上下文,通过解析类路径下的xml来完成BeanDefinition的注册
这里我们就通过现在流行的注解方式来看,像下面这样一行代码就能启动一个容器了
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfAOP.class);
我们是扫描了一个包,直接看看这个构造方法
源代码如下:

上面初始化的两个类我们上一节也提过了
-
AnnotatedBeanDefinitionReader: 读取注解生成BeanDefinition并注册
-
ClassPathBeanDefinitionScanner: 扫描类路径生成BeanDefinition并注册
这里是扫描的包,所以无疑是会执行 ClassPathBeanDefinitionScanner.doScan 方法,我们下面再说
二、IOC启动流程
先看一下启动的流程refresh():

三、重点
我们重点关注 和 Bean相关的内容,我们下面一个个看(注册代表放入工厂):
1、扫描并注册BeanDefination
2、BeanFactory后置处理(invokeBeanFactoryPostProcessors)
3、实例化并注册Bean后置处理器(registerBeanPostProcessors)
4、遍历BeanDefination,实例化单例Bean(finishBeanFactoryInitialization)
refresh() 流程如下:

四、扫描并注册BeanDefination
我们上面说了,我们采用的方式是包扫描,所以最终调用的是 ClassPathBeanDefinitionScanner.doScan 方法,在这个方法中我们重点关注两个:
一个是加载并过滤资源 findCandidateComponents()
一个是注册放入工厂registerBeanDefinition()

1、加载并过滤资源
为什么要过滤资源?因为加载并不是直接加载被注解标识的类,而是加载了所有的类,然后再判断具体需要把哪些变成BeanDefination,所以需要过滤一次
ClassPathScanningCandidateComponentProvider.scanCandidateComponents:

this.isCandidateComponent:
该方法中就会根据过滤器,对这些资源过滤,最终获取的资源就是我们要加载的Bean(内置了一个AnnotationTypeFilter过滤器就是对 @Component注解过滤)

五、注册BeanDefination
要加载的Bean对象会被解析封装成BeanDefination,里面就是Bean对象相关的所有信息,最终调用的就是工厂中的注册BeanDefination的方法registerBeanDefinition(),信息会保存在工厂内的集合里面
DefaultListableBeanFactory.registerBeanDefinition():

六、BeanFactory后置处理
这个在上一节也说过了,对BeanDefination和BeanFactory的后置处理,其实就是对下面这三类接口做一个处理,将实现了这三类接口的实现类找出来排序,挨个执行里面的方法,
总得来说就是对BeanDefination和BeanFactory做一个后置的处理
-
BeanDefinitionRegistry
-
BeanFactoryPostProcessor
-
BeanDefinitionRegistryPostProcessor
最终会执行下面这个方法,这个方法还挺长,我就只截图部分了,重点是掌握以上这些接口,知道这些接口可以对BeanDefination和BeanFactory做一个后置的处理就可以了
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors:

七、注册Bean后置处理器
这里只是把Bean的后置处理器给全找出来放到BeanFactory中去,在后面Bean实例化、初始化、属性赋值的时候才执行生效
PostProcessorRegistrationDelegate.registerBeanPostProcessors:

先找到全部的然后处理、排序,然后注册放入工厂

八、遍历 BeanDefination,实例化单例 Bean
这一步就是最感兴趣的Bean的生命周期了,前面的准备工作都做完了,BeanDefination和BeanPostProcessor都放入工厂beanFactory中,还是老规矩只看重点,其他的一律跳过,
主流程都不理解看其他的只会懵逼,我们先看一张关于Bean生成的图:

入口就是我们下面这个方法,也就是IOC容器启动最关键一步了,从图上看真正的逻辑体现在doGetBean处,我将整个过程最关键的位置分成三步,也就是实例化、属性赋值、初始化,中间插入后置处理器的一些方法处理,
这中间关于三级缓存的地方我会提一下,但是不会深入介绍,之后再说

1、preInstantiateSingletons
DefaultListableBeanFactory.preInstantiateSingletons
这个方法需要记住几个点:
第一点:普通的Bean和实现了FactoryBean接口的Bean 生成流程是不同的

第二点:Bean都生成完成后,会判断Bean是否实现了SmartInitializingSingleton接口,实现了的Bean还会执行该接口的afterSingletonsInstantiated方法

第三点:FactoryBean和单例Bean都会执行getBean方法,getBean又会调用doGetBean方法

2、doGetBean(我们只关注单例)
a、首先会先判断Bean是否已经生成了
b、没生成就走getSingleton方法(对于单例而已)
c、getSingleton执行的时候就会调用那个lambda表达式,也就是会执行createBean方法
d、生成的Bean对象都要判断一次是不是FactoryBean,是的话还要特殊处理一次

3、createBean
AbstractAutowireCapableBeanFactory.createBean
这里很简单,上一节说过了有些拓展的Bean后置处理器会在Bean实例化前执行,所以在一步里面手动实例化了已经存在的bean就不需要再往下走流程了直接返回,正常的Bean都会往下走

4、实例化前执行
resolveBeforeInstantiation
这一步了解一下就好了,毕竟少用,实例化前执行的接口就是 InstantiationAwareBeanPostProcessor继承了BeanPostProcessor

5、doCreateBean
总得来说就分成了三步,实例化、属性赋值、初始化(Bean的生命周期就在这了),过程里面包含一个三级缓存的重点

6、实例化
createBeanInstance
这里就是利用反射实例化,然后将实例化对象包装成了BeanWrapper

7、populateBean 属性赋值
这里就是对Bean里面的属性赋值和依赖bean的注入,同时实例化后执行的方法在里面也会执行
注入需要去容器中找对应的Bean,这里有两个查找方法根据Bean name 和根据Bean type
之后后置处理器的拓展点又会生效执行,InstantiationAwareBeanPostProcessor 内的两个属性赋值的方法
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
if (bw == null) {
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
} else {
if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
Iterator var4 = this.getBeanPostProcessorCache().instantiationAware.iterator();
while(var4.hasNext()) {
// 实例后执行
// 这里会判断实例化后执行的那个返回值true 或者 false
// false代表该实例 不需要属性注入
InstantiationAwareBeanPostProcessor bp = (InstantiationAwareBeanPostProcessor)var4.next();
if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
PropertyValues pvs = mbd.hasPropertyValues() ? mbd.getPropertyValues() : null;
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == 1 || resolvedAutowireMode == 2) {
MutablePropertyValues newPvs = new MutablePropertyValues((PropertyValues)pvs);
// 属性注入 根据Bean name去容器中找然后注入
if (resolvedAutowireMode == 1) {
this.autowireByName(beanName, mbd, bw, newPvs);
}
// 属性注入 根据Bean Type去容器中找然后注入
if (resolvedAutowireMode == 2) {
this.autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
boolean hasInstAwareBpps = this.hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = mbd.getDependencyCheck() != 0;
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
PropertyValues pvsToUse;
for(Iterator var9 = this.getBeanPostProcessorCache().instantiationAware.iterator(); var9.hasNext(); pvs = pvsToUse) {
// 这里InstantiationAwareBeanPostProcessor 中给属性赋值的两个方法也会执行
// 上一节说过了 不多说了
InstantiationAwareBeanPostProcessor bp = (InstantiationAwareBeanPostProcessor)var9.next();
pvsToUse = bp.postProcessProperties((PropertyValues)pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = bp.postProcessPropertyValues((PropertyValues)pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
}
}
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
this.checkDependencies(beanName, mbd, filteredPds, (PropertyValues)pvs);
}
if (pvs != null) {
this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs);
}
}
}
8、initializeBean 初始化
1、先会执行一个拓展点BeanFactoryAware
2、然后初始化前执行(BeanPostProcessors.postProcessBeforeInitialization)
3、初始化(利用反射执行init()方法、InitializingBean拓展点)

4、然后初始化后执行 (BeanPostProcessors.postProcessAfterInitialization)
9、getSingleton
DefaultSingletonBeanRegistry.getSingleton
正常会优先执行getSingleton,只不过这里面内部会执行那个lambda表达式,还是要去执行createBean方法,最终就是会把Bean加入到一级缓存,同时删除掉其他缓存

到这Bean的流程就结束啦
九、总结
1、整体上看Bean流程为:BeanDefination ---> 实例化 ---> 属性赋值 ---> 初始化
2、后置处理器可以对上述流程各阶段前后做出相应的修改和调整
3、再细数一下过程中的拓展接口:
-
BeanDefinitionRegistryPostProcessor:对BeanDefination后置处理
-
BeanFactoryPostProcessor:对BeanFactory后置处理
-
BeanPostProcessor:初始化前后处理
-
InstantiationAwareBeanPostProcessor:实例化前后、属性赋值、初始化前后
-
InitializingBean:初始化执行
-
BeanFactoryAware:获取容器中的工厂
-
ApplicationContextAware:获取容器上下文
-
SmartInitializingSingleton:Bean全生成完了后执行
4、源码很多,但是我们挑自己感兴趣的那部分重点来看,就能形成一个结构化思维,最后再看一下图


浙公网安备 33010602011771号