IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Spring源码学习三——Bean的生命周期主流程 -> 正文阅读

[Java知识库]Spring源码学习三——Bean的生命周期主流程

一、实例化

前文讲到容器启动方法refresh()里面,调用finishBeanFactoryInitialization()方法会实例化所有非懒加载的单例bean,bean的生命周期得入口就在这里在这里插入图片描述
前面那些都不重要,进入红框中的方法
在这里插入图片描述
beanNames里面是BeanDefinition的名称,singletonObjects是单例池。比较一下还有一些我们自己创建的类未被实例化
在这里插入图片描述
如果一个bean不是抽象的、是单例的且不是懒加载就会进入if,然后如果这个bean是FactoryBean,会特殊处理,但最终都会进入getBean(),这里没有直接创建bean,而是先从缓存里面拿,如果没有就创建bean,进入getBean

1.1 getBean

进入doGetBean();spring里面带do的方法就是真正做事的。
在这里插入图片描述
getSingleton(beanName);第一次得到的肯定是空,往下跳过不重要的部分
在这里插入图片描述
进入getSingleton
在这里插入图片描述
这行调用了函数式接口的getObject()
在这里插入图片描述
继续进入,就回到了lambda表达式里面的createBean(),开始创建bean的实例

1.2 createBean

进入createBean之后一路往下到达doCreateBean,真正做事的方法
在这里插入图片描述
先进入createBeanInstance,往下走到instantiateBean
在这里插入图片描述
注释是说没有特殊处理:简单的使用无参构造方法
在这里插入图片描述
进入beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
在这里插入图片描述
拿到无参构造器方法保存到BeanDefinition的resolvedConstructorOrFactoryMethod属性
在这里插入图片描述
最终调用newInstance得到了实例对象,其实就是用了反射机制生成对象

二、初始化

在这里插入图片描述
看注释,这里就是初始化开始的地方

2.1 populateBean

populateBean()方法就是属性注入,如果有依赖其他bean就会先完成其他bean的生命周期。这就可能会引发循环依赖,循环依赖的问题我在其他文章中有讲,这里就不详细说了,现在只关心主流程。

2.2 Aware回调

exposedObject = initializeBean(beanName, exposedObject, mbd);–>invokeAwareMethods(beanName, bean);
在这里插入图片描述
Aware的顺序是BeanNameAware–>BeanClassLoaderAware–>BeanFactoryAware

2.3 前置增强postProcessBeforeInitialization

返回到initializeBean方法从wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);进入
在这里插入图片描述
这里执行了所有注册过的BeanPostProcessor的postProcessBeforeInitialization方法,用来处理指定的bean。

2.3.1 @PostConstruct

这里特别注意一下有个CommonAnnotationBeanPostProcessor的增强器,它的构造方法
在这里插入图片描述
会设置初始化注解PostConstruct,它的postProcessBeforeInitialization继承至InitDestroyAnnotationBeanPostProcessor
在这里插入图片描述
postProcessBeforeInitialization执行进入

findLifecycleMetadata(bean.getClass());–>buildLifecycleMetadata()
在这里插入图片描述

这里将@PostConstruct注解的方法加入到了currInitMethods是一个List,最终加入了LifecycleMetadata的initMethods
所以注解@PostConstruct多个方法都会被执行,继续看在哪里执行,回到postProcessBeforeInitialization,从metadata.invokeInitMethods(bean, beanName);进入
在这里插入图片描述
这里执行所有的初始化方法

2.4 执行初始化方法

2.4.1 afterPropertiesSet

返回到initializeBean方法从invokeInitMethods(beanName, wrappedBean, mbd);进入
在这里插入图片描述
先检查是否实现InitializingBean,如果有就执行afterPropertiesSet方法,继续往下
在这里插入图片描述
getInitMethodName()拿到的是手动指定的初始化方法,即xml文件配置bean时指定的init-method属性。之后执行init-method指定的方法

2.4.2 init-method

mbd.getInitMethodName()获取的是initMethodName,看看它在何时赋值
在这里插入图片描述
最终发现是在xml解析的时候赋值的
在这里插入图片描述
在这里插入图片描述
initMethodName类型是String,也就是说只能有一个init-method方法

2.5 后置增强postProcessAfterInitialization

返回到initializeBean方法从wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
进入
在这里插入图片描述
执行所有的后置增强

三、销毁

3.1 destroy

在Spring容器关闭的时候,会去销毁所有的单例Bean
在这里插入图片描述
进入

close()–doClose();–>destroyBeans();–>super.destroySingletons();–> destroySingleton(disposableBeanNames[i]);–>super.destroySingleton(beanName);–>destroyBean(beanName, disposableBean);–>bean.destroy();
在这里插入图片描述

3.1.1 @PreDestroy

bean在销毁的时候会执行DestructionAwareBeanPostProcessor的postProcessBeforeDestruction方法
在这里插入图片描述
InitDestroyAnnotationBeanPostProcessor实现了DestructionAwareBeanPostProcessor,因此会执行它的postProcessBeforeDestruction,进而执行metadata.invokeDestroyMethods(bean, beanName);
前面讲过@PostConstruct,在那里同时处理的还有@PreDestroy注解。最终将@PreDestroy注解的方法名添加到了LifecycleMetadata.destroyMethods,而这些方法都将在这里一并执行

3.1.2 DisposableBean

在这里插入图片描述

如上图,如果bean实现了DisposableBean接口,会先执行它自己实现的destroy方法

3.1.3 destroy-method

最后会执行xml指定的destroy-method方法,与init-mehod类似。
在这里插入图片描述
这里的destroyMethodName就是来自xml指定的destroy-method

四、总结

在这里插入图片描述

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-05-06 10:55:43  更:2022-05-06 10:57:06 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 0:25:57-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码