参考源

https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click

https://www.bilibili.com/video/BV12Z4y197MU?spm_id_from=333.999.0.0

《Spring源码深度解析(第2版)》

版本

本文章基于 Spring 5.3.15


Bean 的生命周期示意图(存在循环依赖和 AOP)

执行创建 Bean

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException

AbstractAutowireCapableBeanFactory

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
// 实例化 Bean
BeanWrapper instanceWrapper = null;
// 是否为单例
if (mbd.isSingleton()) {
// 有可能在本 Bean 创建之前
// 就有其他 Bean 把当前 Bean 给创建出来了(比如依赖注入过程中)
// 所以这里先将其删除
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 创建 Bean 实例
// 根据指定 bean 使用对应的策略创建新的实例
// 如:工厂方法、构造函数自动注入、简单初始化
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// 获得 Bean 对象
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
} // 后置处理合并的 BeanDefinition
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
// 应用 MergedBeanDefinitionPostProcessors
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
} catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
} // 是否提前暴露
// 为了解决循环依赖提早缓存单例创建工厂
// 是否需要提早曝光:单例 & 允许循环依赖 & 当前 bean 正在创建中
// 用于检测循环依赖
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
}
// 添加到三级缓存
// 为避免后期循环依赖,可以在 bean 初始化完成前将创建实例的 ObjectFactory 加入工厂
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
} Object exposedObject = bean;
try {
// 属性填充
// 对 bean 进行填充,将各个属性值注入,其中,可能存在依赖于其他 bean 的属性,则会递归初始依赖 bean
populateBean(beanName, mbd, instanceWrapper);
// 初始化
// 调用初始化方法,比如 init-method
exposedObject = initializeBean(beanName, exposedObject, mbd);
} catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
} else {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
} if (earlySingletonExposure) {
// 获取单例对象
Object earlySingletonReference = getSingleton(beanName, false);
// 在检测到有循环依赖的情况下才会不为空
if (earlySingletonReference != null) {
// 如果 exposedObject 没有在初始化方法中被改变,也就是没有被增强
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
} else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
// 检测依赖
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
// 因为 bean 创建后其所依赖的 bean 一定是已经创建的
// actualDependentBeans 不为空则表示当前bean 创建后其依赖的 bean 却没有全部创建完,也就是说存在循环依赖
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
} try {
// 根据 scope 注册 bean
registerDisposableBeanIfNecessary(beanName, bean, mbd);
} catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
} return exposedObject;
}

实例化

创建 Bean 实例

根据指定 bean 使用对应的策略创建新的实例

如:工厂方法、构造函数自动注入、简单初始化

createBeanInstance(beanName, mbd, args)

AbstractAutowireCapableBeanFactory

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// 解析 class
Class<?> beanClass = resolveBeanClass(mbd, beanName); if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
} Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
// 如果工厂方法不为空则使用工厂方法初始化策略
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
} boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
// 一个类有多个构造函数,每个构造函数都有不同的参数, 所以调用前需要先根据参数锁定构造函数或对应的工厂方法
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
// 如果已经解析过则使用解析好的构造函数方法不需要再次锁定
if (resolved) {
// 构造函数自动注入
if (autowireNecessary) {
return autowireConstructor(beanName, mbd, null, null);
}
// 使用默认构造函数构造
else {
return instantiateBean(beanName, mbd);
}
} // 需要根据参数解析构造函数
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
// 构造函数自动注入
return autowireConstructor(beanName, mbd, ctors, args);
} ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
// 使用默认构造函数构造
return instantiateBean(beanName, mbd);
}

是否提早暴露

是否提前暴露

为了解决循环依赖提早缓存单例创建工厂

是否需要提早曝光:单例 & 允许循环依赖 & 当前 bean 正在创建中

boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName))

DefaultSingletonBeanRegistry

/**
* 单例是否正在创建中
*/
private final Set<String> singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap<>(16)); public boolean isSingletonCurrentlyInCreation(String beanName) {
return this.singletonsCurrentlyInCreation.contains(beanName);
}

添加到三级缓存

添加到三级缓存

为避免后期循环依赖,可以在 bean 初始化完成前将创建实例的 ObjectFactory 加入工厂

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

DefaultSingletonBeanRegistry

// 一级缓存:也叫单例池。
// 用于保存 BeanName 和创建 bean 实例之间的关系,bean name -> bean instance
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256); // 二级缓存:存放提前AOP生成的代理对象,保持代理对象的单例。
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16); // 三级缓存:存放用于生成代理对象的Lambda,用于循环依赖中生成代理对象,以打破循环依赖。
// 用于保存 BeanName 和创建 bean 的工厂之间的关系,bean name -> ObjectFactory
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16); // 用来保存当前所有已注册的 bean
private final Set<String> registeredSingletons = new LinkedHashSet<>(256); protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
// 为了保持操作的原子性,加锁
synchronized (this.singletonObjects) {
// 单例池中是否存在
if (!this.singletonObjects.containsKey(beanName)) {
// 对应记录放人三级缓存
this.singletonFactories.put(beanName, singletonFactory);
// 二级缓存移除对应记录
this.earlySingletonObjects.remove(beanName);
// 添加到已注册的 Bean
this.registeredSingletons.add(beanName);
}
}
}

获取单例对象

获取单例对象

getSingleton(beanName, false)

DefaultSingletonBeanRegistry

// 一级缓存:也叫单例池。
// 用于保存 BeanName 和创建 bean 实例之间的关系,bean name -> bean instance
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256); // 二级缓存:存放提前AOP生成的代理对象,保持代理对象的单例。
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16); // 三级缓存:存放用于生成代理对象的Lambda,用于循环依赖中生成代理对象,以打破循环依赖。
// 用于保存 BeanName 和创建 bean 的工厂之间的关系,bean name -> ObjectFactory
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16); protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 检查单例池中是否存在实例
Object singletonObject = this.singletonObjects.get(beanName);
// 想要获取的 Bean 正在创建中,说明出现了循环依赖
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
// 从二级缓存中获取该 Bean 的代理对象
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
// 如果二级缓存没有,则锁定单例池并进行处理
synchronized (this.singletonObjects) {
// 检查单例池中是否存在实例
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
// 从二级缓存中获取该 Bean 的代理对象
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null) {
// 当某些方法需要提前初始化的时候则会调用 addSingletonFactory 方法将对应的 ObjectFactory 初始化策略存储在三级缓存中
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
// 从三级缓存中找到了
if (singletonFactory != null) {
// 调用预先设定的 getObject 方法
// 这里会执行 Lambda 表达式
singletonObject = singletonFactory.getObject();
// 记录在二级缓存中,删除三级缓存对应记录
// 二级缓存和三级缓存互斥
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
return singletonObject;
}

提前 AOP

提前 AOP 就是三级缓存中存放的 Lambda 表达式执行的方法

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

AbstractAutowireCapableBeanFactory

protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) {
// 提前 AOP
exposedObject = bp.getEarlyBeanReference(exposedObject, beanName);
}
}
return exposedObject;
}

提前 AOP

getEarlyBeanReference(exposedObject, beanName)

AbstractAutoProxyCreator

public Object getEarlyBeanReference(Object bean, String beanName) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// 早期进行 AOP,则将标识传入
// 供后面再进行 AOP 时进行判断
this.earlyProxyReferences.put(cacheKey, bean);
// 必要时填充
return wrapIfNecessary(bean, beanName, cacheKey);
}

正常 AOP

初始化

initializeBean(beanName, exposedObject, mbd)

AbstractAutowireCapableBeanFactory

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
} else {
// 对特殊的 bean 处理:Aware、BeanClassLoaderAware、BeanFactoryAware
invokeAwareMethods(beanName, bean);
} Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 初始化前
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
} try {
// 激活用户自定义的 init 方法
invokeInitMethods(beanName, wrappedBean, mbd);
} catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
// 初始化后
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
} return wrappedBean;
}

初始化后

applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName)

AbstractAutowireCapableBeanFactory

public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {

   Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
// 初始化后的后处理
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}

初始化后的后处理

postProcessAfterInitialization(result, beanName)

AbstractAutoProxyCreator

public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// 如果前面没有进行过 AOP,这里进行 AOP
// 如果前面进行过 AOP,删除对应记录,这里不进行 AOP
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}

Spring源码 21 Bean生命周期的更多相关文章

  1. Spring源码系列 — Bean生命周期

    前言 上篇文章中介绍了Spring容器的扩展点,这个是在Bean的创建过程之前执行的逻辑.承接扩展点之后,就是Spring容器的另一个核心:Bean的生命周期过程.这个生命周期过程大致经历了一下的几个 ...

  2. Spring源码之Bean生命周期

    https://www.jianshu.com/p/1dec08d290c1 https://www.cnblogs.com/zrtqsk/p/3735273.html 总结 将class文件加载成B ...

  3. Spring之BeanFactory及Bean生命周期

    1.spring通过BeanFactory灵活配置.管理bean,Spring对管理的bean没有任何特别的要求,完全支持对POJO的管理: 2.BeanFactory有个ApplicationCon ...

  4. 深入源码理解SpringBean生命周期

    概述 本文描述下Spring的实例化.初始化.销毁,整个SpringBean生命周期,聊一聊BeanPostProcessor的回调时机.Aware方法的回调时机.初始化方法的回调及其顺序.销毁方法的 ...

  5. Vue2.0源码阅读笔记--生命周期

    一.Vue2.0的生命周期 Vue2.0的整个生命周期有八个:分别是 1.beforeCreate,2.created,3.beforeMount,4.mounted,5.beforeUpdate,6 ...

  6. Laravel源码分析--Laravel生命周期详解

    一.XDEBUG调试 这里我们需要用到php的 xdebug 拓展,所以需要小伙伴们自己去装一下,因为我这里用的是docker,所以就简单介绍下在docker中使用xdebug的注意点. 1.在php ...

  7. angular11源码探索[DoCheck 生命周期和onChanges区别]

    网站 https://blog.thoughtram.io/ https://juristr.com/ https://www.concretepage.com/angular/ https://ww ...

  8. Spring BeanFactory 初始化 和 Bean 生命周期

    (version:spring-context-4.3.15.RELEASE) AbstractApplicationContext#refresh() public void refresh() t ...

  9. 【spring源码】bean的实例化(转载)

    首先来看一段代码,看过上一节的朋友肯定对这段代码并不陌生.这一段代码诠释了Spring加载bean的完整过程,包括读取配置文件,扫描包,加载类,实例化bean,注入bean属性依赖. 上一节介绍了Sp ...

随机推荐

  1. 记一次Tomcat卡死在 Deploying web application 步骤的问题

    公司有一个历史的遗留项目是传统的MVC架构的前后不分离的项目,一开始使用JDK1.7写的,后来前一阵老板说想在这个远古项目上加点功能,顺带换换皮,于是乎一帮程序员们就用JDK1.8重新翻新了一遍项目顺 ...

  2. 参与 2022 第二季度 Flutter 开发者调查

    2022 Google I/O 大会正式落下帷幕,Flutter 作为 14 个开发者产品和平台中的一款,吸引了来自全球的很多开发者们的关注.随着全国很多地方已经进入夏季,Flutter 今年第二季度 ...

  3. Solon 1.8.0 发布,云原生微服务开发框架

    相对于 Spring Boot 和 Spring Cloud 的项目 启动快 5 - 10 倍 qps 高 2- 3 倍 运行时内存节省 1/3 ~ 1/2 打包可以缩小到 1/2 ~ 1/10(比如 ...

  4. 变量作用域——JavaSE基础

    变量作用域 局部变量.成员变量.静态变量的区别 类型 声明位置 从属于 生命周期 局部变量 方法或语句块内部 方法/语句块 从声明位置开始,直到方法或语句块执行完毕,局部变量消失 成员变量 (实例变量 ...

  5. Linux版本的项目环境搭建

    项目环境docker及docker-compose文档 1.Linux环境介绍 centos7.6 16G以上内存空间(至少8G) 2.静态IP设置 1.找到配置文件 cd /etc/sysconfi ...

  6. Java 基础常见知识点&面试题总结(上),2022 最新版!| JavaGuide

    你好,我是 Guide.秋招即将到来,我对 JavaGuide 的内容进行了重构完善,公众号同步一下最新更新,希望能够帮助你. 基础概念与常识 Java 语言有哪些特点? 简单易学: 面向对象(封装, ...

  7. C语言- 基础数据结构和算法 - 动态数组

    听黑马程序员教程<基础数据结构和算法 (C版本)>,照着老师所讲抄的, 视频地址https://www.bilibili.com/video/BV1vE411f7Jh?p=1 喜欢的朋友可 ...

  8. 24.Haproxy搭建Web群集

    Haproxy搭建Web群集 目录 Haproxy搭建Web群集 Haproxy简介 常见的Web集群调度器 软件类 硬件类 Haproxy应用分析 HAProxy的主要特性 HAProxy常见的8种 ...

  9. 8.shell编程之免交互

    shell编程之免交互 目录 shell编程之免交互 Here Document免交互 免交互定义 Here Document变量设定 多行的注释 expect expect 定义 expect基本命 ...

  10. web自动化之元素定位篇

    一.web自动化元素定位的方式有8种.------腾讯课堂 1.1 id定位: 1.2 class定位: 1.3 classname定位 1.4 tag_name 1.5