我是靠谱客的博主 腼腆小虾米,最近开发中收集的这篇文章主要介绍【Spring】Bean生命周期源码分析 下篇 属性填充以及初始化流程,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

1.实例化前推断构造方法

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean

image-20220403104229519

创建了一个 BeanWrapper对象用来报装实例化的bean

开始实例化

instanceWrapper = createBeanInstance(beanName, mbd, args);

image-20220403104722942

跟进去

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance

image-20220403104803001

获取bean的class类型

Class<?> beanClass = resolveBeanClass(mbd, beanName);

如果bean指定了工厂方法,将会进这个if判断

底层会获取工厂方法【静态工厂方法|实例化方法】--> 然后解析方法入参 --> 然后执行反射调用创建实例 --> 封装为包装对象返回.
if (mbd.getFactoryMethodName() != null) {
			return instantiateUsingFactoryMethod(beanName, mbd, args);
		}

如果bean是原型,将走这个分支

image-20220403105138275

如果不是原型bean,将执行推断构造方法的方法

Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);

image-20220403105258260

image-20220403105344834

现在正在实例化的是bean A 没有显示提供构造方法,将默认提供一个无参构造 但是spring没有推断出任何构造方法

image-20220403105509464

接着调用getPreferredConstructors,获取默认的构造方法

ctors = mbd.getPreferredConstructors();

image-20220403105619176

结果还是什么都没拿到 最终调用 instantiateBean 方法

// No special handling: simply use no-arg constructor.
		return instantiateBean(beanName, mbd);

走到这里的条件 没有创建bean的回调方法 && 没有工厂方法 && 构造函数的参数未解析完毕 && 没有预先指定的默认构造函数

跟进 instantiateBean方法

image-20220403105913726

beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);

先看下返回的实例化策略是什么

image-20220403110042850

默认的创建策略为:CglibSubclassingInstantiationStrategy

2.实例化bean

跟进 org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate

image-20220403110258931

拿到bean的class对象,获取默认的构造方法,将获取到的构造函数设置到bd中,最后调用 BeanUtils.instantiateClass(constructorToUse),并把构造方法传过去了

来到 org.springframework.beans.BeanUtils.instantiateClass

image-20220403110623024

在BeanUtils.instantiateClass方法中 开启暴力反射,最终构造方法对象调用newInstance方法完成实例化

image-20220403110841317

可以看到已经实例化出来了

回到 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean方法

image-20220403111419852

2.1 调用bean的MergedBeanDefinitionPostProcessor 后期处理器

再次调用bean的后期处理器,此时bean已经实例化了,但没有完成属性注入

依次调用所有MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition方法,用来处理类中使用注解标注的属性,并放入到缓存中.

applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);

image-20220403111643781

3.Bean实例化后,添加到三级缓存

往下继续走,看到又有一个三连判断

当前bean是否是单例,是否允许循环依赖,是否是正在创建的,都满足继续往下走

image-20220403112121449

调用addSingletonFactory 参数又有一个lombad表达式,用的非常多

addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));

image-20220403112256280

跟进去

org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.addSingletonFactory

image-20220403112433721

`如果当前的单实例缓存池中还没有beanName对应的单实例bean,

!this.singletonObjects.containsKey(beanName)

将lombad表达式放到三级缓存中,

this.singletonFactories.put(beanName, singletonFactory);

并从二级缓存中除beanName对应的bean实例

this.earlySingletonObjects.remove(beanName);

`将当前的beanName保存到已经注册的bean对应的Set集合中,标识其已经注册过

this.registeredSingletons.add(beanName);

回到addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));

看下重写方法做了什么事情 注意此时没有调用

获取所有的后置处理器判断是不是实现了SmartInstantiationAwareBeanPostProcessor接口挨个调用SmartInstantiationAwareBeanPostProcessor的getEarlyBeanReference Spring解决AOP代理对象的循环依赖问题的核心

image-20220403113143498

接着doCreateBean方法往下看,紧接着调用了populateBean(beanName, mbd, instanceWrapper) 开始进入属性填充阶段

image-20220403113642811

4.实例化后的InstantiationAwareBeanPostProcessor后置处理

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean

实例化后调用 InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()方法

看过上篇博文知道在实例化前也调用了InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation

image-20220403113857627

如果我们重写了 InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()方法,并且返回false,将不会进行属性填充,默认是true

`获取当前正在实例化的bean的所有属性

PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

判断属性填充的方法 @Autowired既不属于ByName也不属于ByType

image-20220403120849770

当前bean是否有InstantiationAwareBeanPostProcessor类型的后置处理器

boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();

依赖检测

boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

如果有InstantiationAwareBeanPostProcessor类型的后置处理器 将进入if判断逻辑,执行后置处理器方法

image-20220403121147250

5.属性填充阶段

真正的属性填充方法applyPropertyValues(beanName, mbd, bw, pvs);

applyPropertyValues(beanName, mbd, bw, pvs);

image-20220403121420005

跟进applyPropertyValues

image-20220403121534423

最终通过反射调用setter方法属性填充

6.初始化前执行三个aware回调方法

回到 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean 方法

image-20220403122213607

属性填充完毕后立马执行初始化方法

接着看初始化方法

exposedObject = initializeBean(beanName, exposedObject, mbd);

image-20220403122307427

跟进去

image-20220403122323649

调用了三个aware回调方法 BeanNameAware -> BeanClassLoaderAware -> BeanFactoryAware

image-20220403122631719

执行完三个回调方法后,调用 applyBeanPostProcessorsBeforeInitialization 又是一个后置处理器

wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);

7.初始化前执行BeanPostProcessor的postProcessBeforeInitialization

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization

image-20220403122821818

如果postProcessBeforeInitialization方法返回了一个对象,那么当前正在初始化的bean将被替换 当前正在初始化的bean是有属性值的

执行完BeanPostProcessor的初始化前置方法后,将执行 invokeInitMethods 方法,执行初始化方法

8.执行初始化方法

invokeInitMethods(beanName, wrappedBean, mbd);

image-20220403123223622

首先判断是不是实现了 InitializingBean接口 如果实现了,将执行 afterPropertiesSet方法

image-20220403123324702

判断有没有指定初始化方法,如果有,则通过反射执行指定的初始化方法

image-20220403123421602

初始化方法执行完毕后回到initializeBean 方法,继续往下走,将执行执行BeanPostProcessor的后置方法image-20220403123618646

9. 初始化后执行BeanPostProcessor的postProcessAfterInitialization

applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);

wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);

image-20220403123737843

BeanPostProcessor.postProcessAfterInitialization方法就牛逼了,代理类就在这里创建的,AOP基于此处实现的

在回到 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean,

从initializeBean(beanName, exposedObject, mbd)出来

image-20220403124304428

继续往下走 如果出现了循环依赖

来到getSingleton(beanName, false)方法

image-20220403124337224

注意一点 getSingleton(beanName, false); 调用 getSingleton方法传的参数时false,也就不会去三级缓存中拿

10.添加到单例缓冲池

bean已经实例化后,回到 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton 继续往下走

image-20220403125446954

将调用afterSingletonCreation方法,将beanName从正在创建的beanName集合中删除

image-20220403125722699

image-20220403125630910

然后调用addSingleton(beanName, singletonObject);将当前bean添加到单例缓冲池中

image-20220403125754389

`将创建好的单实例bean放入到单例缓存池中

this.singletonObjects.put(beanName, singletonObject);

`/ 从三级缓存中删除

this.singletonFactories.remove(beanName);

`从二级缓存中删除

this.earlySingletonObjects.remove(beanName);

`保存到已注册单实例Bean名称集合中

this.registeredSingletons.add(beanName);

至此 Spring中一个Bean的生命周期走完,流程比较多,下篇博文将详细画图,并解释三级缓存是如何解决循环依赖问题的

最后

以上就是腼腆小虾米为你收集整理的【Spring】Bean生命周期源码分析 下篇 属性填充以及初始化流程的全部内容,希望文章能够帮你解决【Spring】Bean生命周期源码分析 下篇 属性填充以及初始化流程所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(26)

评论列表共有 0 条评论

立即
投稿
返回
顶部