gpt4 book ai didi

SpringBean的一生

转载 作者:撒哈拉 更新时间:2024-04-01 12:40:21 55 4
gpt4 key购买 nike

Spring Bean 的一生包括其从创建到消亡的整个过程:

实例创建 => 填充 => 初始化 => 使用 => 销毁.

这里需要注意的是,从 bean 实例的创建到可以使用之间还包括【填充】和【初始化】两个步骤.

AbstractAutowireCapableBeanFactory::createBean:bean 创建核心方法,包含创建、填充 bean 实例及应用 post-processors 等逻辑.

一、实例创建

1、实例化前置处理

InstantiationAwareBeanPostProcessor 为 BeanPostProcessor 子接口,用以提供【创建实例】前后回调处理.

如果有实现 InstantiationAwareBeanPostProcessor 接口,则应用此接口,返回结果如果不为 null,则直接返回作为 bean 实例.

2、doCreateBean

实际用于执行 bean 创建的方法,所有的创建、填充、初始化、注册销毁等逻辑都在此处处理.

BeanWrapper:Spring 底层 JavaBean 结构核心接口,提供了分析和管理 JavaBean 的相关操作。不直接使用,通常隐式的通过 BeanFactory 或者 DataBinder 来使用。此处执行逻辑即为使用 BeanWrapper 对象.

factoryBeanInstanceCache:存储 FactoryBean name --> BeanWrapper 键值映射。执行实例创建伊始,会先从 factoryBeanInstanceCache 查询获取,存在则直接获取(获取后删除)使用.

好吧,这里有个问题,为什么会有个 factoryBeanInstanceCache 缓存?

源头在于对单例 FactoryBean 类型操作,getSingletonFactoryBeanForTypeCheck.

创建 bean 实例 createBeanInstance:

优先级顺序:

  • 通过 InstanceSupplier 创建(5.0以后) 。

  • 通过工厂方法创建 。

  • 构造函数创建 。

至此,bean 实例已创建完毕.

此处还有一个 post-processor 处理:MergedBeanDefinitionPostProcessor,用于 bean 定义修改(只针对 RootBeanDefinition:merge 了多个来源 BeanDefinition 的运行时视图).

3、单例实例提前暴露

为了解决单例循环依赖问题,提前将未完全创建好的单例实例缓存起来.

这里说的未完全创建好是指还不能正常使用.

earlySingletonExposure 条件:

  • 单例:scope 为 “singleton” 或者 ”“.

  • 允许自动处理循环依赖:allowCircularReferences 默认 true 。

  • 单例 bean 处于创建中:DefaultSingletonBeanRegistry:singletonsCurrentlyInCreation 存储所有处于创建中的 bean 名称.

addSingletonFactory:

将 singletonFactory 添加到 singletonFactories 缓存中,以备解决循环依赖使用.

singletonFactories 是什么呢?

字面意思为单例工厂缓存(bean name -> ObjectFactory ):即所谓的第三级缓存,存储目标 bean 所对应的 bean 工厂对象键值.

那 ObjectFactory 这个对象是怎么获取的呢?

SmartInstantiationAwareBeanPostProcessor::getEarlyBeanReference 。

SmartInstantiationAwareBeanPostProcessor 是 InstantiationAwareBeanPostProcessor 的扩展接口.

InstantiationAwareBeanPostProcessor 我们说过,是作用在创建实例前后。此处为创建实例后情景.

ObjectFactory 虽名为工厂,其实际为用以在 bean 创建早期,访问相应 bean 的一个引用.

什么是早期呢?

就是这会儿,刚创建完实例,还没有进行相应的填充、初始化等后续操作.

那为什么是暴露个引用,而不是直接给出目标对象呢?

因为目标 bean 可能还会经过其它 post-processors 处理。像 AbstractAutoProxyCreator::getEarlyBeanReference 中的代理逻辑处理.

二、填充

属性填充,作用于 AbstractAutowireCapableBeanFactory::populateBean.

1、属性填充前置处理

continueWithPropertyPopulation:是否继续处理属性填充判断.

这里的说明是在执行属性填充前给予任何 InstantiationAwareBeanPostProcessors 一个机会来变更 bean 的状态.

什么意思呢?

就是 InstantiationAwareBeanPostProcessors 的 postProcessAfterInstantiation 处理,对目标 bean 做相应的变更.

做什么变更呢?

这个节点在 Spring 自动注入操作之前,可以执行个性化的属性注入。同时,方法返回值会赋予 continueWithPropertyPopulation,以决定是否执行后续的逻辑.

这里有一个点需要注意:

如果当前 InstantiationAwareBeanPostProcessors::postProcessAfterInstantiation 返回 false,那么 bean 属性填充步骤则就此终止,不会再执行其它的 InstantiationAwareBeanPostProcessors 及后续的 Spring bean 属性填充过程.

2、属性填充

MutablePropertyValues 。

PropertyValues 接口的一个实现,提供对属性的各种操作,同时提供相应的构造函数来支持深度复制及基于 Map 的构造.

自动注入方式:按顺序 BY_NAME => BY_TYPE 。

BY_NAME 。

autowireByName 根据名称填充 。

填充什么呢?

unsatisfiedNonSimpleProperties.

什么是 unsatisfiedNonSimpleProperties 呢?

  • 可写的:即拥有写方法.

  • 需要依赖检查的:基于 ignoredDependencyTypes 属性设置判断.

  • 非本身类型的.

  • 非简单类型属性的:属性本身类型及数组元素类型为非简单类型。包括(基本类型及其包装类型,如 int、Integer 等) 。

注入:

首先根据属性名称判断 bean 存在: 即是否包含在 bean 工厂及外部注册单例 bean.

  • alias 的,会做相应的名称转换.

  • 存在继承关系的,会级联向上查询.

根据属性名称获取 bean:AbstractBeanFactory::getBean.

属性设置.

注册 bean 依赖:dependentBeanMap beanName -> Set<BeanName>,即记录 bean 及其依赖 bean 关系.

BY_TYPE 。

autowireByName 根据类型填充.

一个 BeanFactory 里必须恰好只有一个匹配需要类型.

同样,首先获取需要填充的属性:unsatisfiedNonSimpleProperties.

排除 Object 类型属性,填充没有意义.

处理依赖.

属性设置 。

注册 bean 依赖.

3、依赖检查

依赖检查分为两部分:一个基于 InstantiationAwareBeanPostProcessor::postProcessPropertyValues 处理。一个基于 AbstractBeanDefinition::dependencyCheck 处理.

InstantiationAwareBeanPostProcessor:

对特定的属性进行依赖检查及处理;对特定属性值进行替换,添加或者删除.

如 RequiredAnnotationBeanPostProcessor、 AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor、MockitoPostProcessor等.

dependencyCheck 。

检查所有暴露的属性是否都已赋值.

4、属性赋值

将上述处理过的属性值填充到 bean 实例.

三、初始化

应用工厂回调,定义的初始化方法及post-processors.

1、Aware 处理

Aware 代表了各种各样的资源,处理 Aware 即为将相应的资源添加到 bean 实例中.

如 BeanNameAware、BeanClassLoaderAware、BeanFactoryAware 等.

2、BeanPostProcessorsBeforeInitialization

顾名思义,这里的 BeanPostProcessors 是初始化之前的处理.

如 AbstractAdvisingBeanPostProcessor 检查.

3、执行初始化方法

a)实现了 InitializingBean 接口的 bean,执行相应的 afterPropertiesSet 方法.

b)定义了 initMethod 的,触发相应的方法调用.

两者是否可以同时存在呢?

可以,如果同时存在,但是初始化方法名称不能为 afterPropertiesSet。执行顺序为先 a 后 b.

4、BeanPostProcessorsAfterInitialization

同 2,此处为初始化之后的处理.

如 BeanValidationPostProcessor、ApplicationListenerDetector 等.

其实很多 PostProcessor 是既有 Before 处理逻辑,亦有 After 处理逻辑的,此处不再赘述.

四、disposable bean 注册

bean 工厂维护了一个 disposable bean 列表(bean name --> disposable instance)。在工厂关闭销毁时,同时销毁相应的 bean 实例对象.

定义销毁可以通过实现 DisposableBean 或者 AutoCloseable 接口或者自定义销毁方法.

如果使用一个定义了相应销毁方法的对象,又不想其执行销毁方法时怎么办呢? 注解或者配置其销毁方法为空,如:@Bean(destroyMethod = "").

DestructionAwareBeanPostProcessor:实例销毁前,用户可以自定义执行特定的操作。如:ApplicationListenerDetector 移除相应的 Listener;ScheduledAnnotationBeanPostProcessor 移除定时任务等.

最后此篇关于SpringBean的一生的文章就讲到这里了,如果你想了解更多关于SpringBean的一生的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

55 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com