Spring高手之路-SpringBean的生命周期

目录

SpringBean的生命周期

整体介绍

详细介绍

1.实例化Bean

2.设置属性值

3.检查Aware

4.调用BeanPostProcessor的前置处理方法

5.调用InitializingBean的afterPropertiesSet方法

6.调用自定义init-method方法

7.调用BeanPostProcessor的后置处理方法

8.注册Destruction回调

9.Bean准备就绪

10.调用DisposableBean的destroy方法

11.调用自定义的destory-method

核心部分源码


SpringBean的生命周期

整体介绍

一个SpringBean从出生到销毁的全过程就是它的整个生命周期,需要经历以下几个阶段:

整个生命周期可以大致分为三个大阶段,分别是:创建、使用、销毁。还可以进一步分为5个小的阶段:实例化、初始化(前置处理、初始化、后置处理)、注册Destruction回调、正常使用、销毁。

详细介绍

SpringBean的生命周期详情

1.实例化Bean

Spring容器首先创建Bean实例

AbstractAutowireCapableBeanFactory类中的createBeanInstance方法中实现

2.设置属性值

Spring容器注入必要的属性到Bean中。

AbstractAutowireCapableBeanFactory类中的populateBean方法中处理

3.检查Aware

如果Bean实现了BeanNameAware、BeanClassLoaderAware等这些Aware接口,Spring容器会调用它们。

 在AbstractAutowireCapableBeanFactory类中的initializeBean方法中调用

4.调用BeanPostProcessor的前置处理方法

在Bean初始化之前,允许自定义的BeanPostProcessor对Bean实例进行处理,如修改Bea的状态

BeanPostProcessor的postProcessBeforeInitialization方法会在此时被调用。

AbstractAutowireCapableBeanFactory的applyBeanPostProcessorsBeforeInitialization方法执行

5.调用InitializingBean的afterPropertiesSet方法

提供一个机会,在所有Bean属性设置完成后进行初始化操作。如果Bean实现了InitializingBean接口afterPropertiesSet方法会被调用。
AbstractAutowireCapableBeanFactory的invokelnitMethods方法中调用

6.调用自定义init-method方法

提供一种配置方式,在XML配置中指定Bean的初始化方法。如果Bean在配置文件中定义了初始化方法那么该方法会被调用。
AbstractAutowireCapableBeanFactory的invokelnitMethods方法中调用

7.调用BeanPostProcessor的后置处理方法

在Bean初始化之后,再次允许BeanPostProcessor对Bean进行处理。BeanPostProcessor的postProcessAfterlnitialization方法会在此时被调用。

AbstractAutowireCapableBeanFactory的applyBeanPostProcessorsAfterlnitialization方法执行

8.注册Destruction回调

如果Bean实现了DisposableBean接口或在Bean定义中指定了自定义的销毁方法,Spring容器会为这些Bean注册一个销毁回调,确保在容器关闭时能够正确地清理资源。

AbstractAutowireCapableBeanFactory类中的registerDisposableBeanlfNecessary方法中实现

9.Bean准备就绪

此时,Bean已完全初始化,可以开始处理应用程序的请求了

10.调用DisposableBean的destroy方法

当容器关闭时,如果Bean实现了DisposableBean接口,destroy方法会被调用。

DisposableBeanAdapter的destroy方法中实现

11.调用自定义的destory-method

如果Bean在配置文件中定义了销毁方法,那么该方法会被调用


DisposableBeanAdapter的destroy方法中实现

核心部分源码

可以看到,整Bean的创建的过程都依赖于AbstractAutowireCapableBeanFactory这个类,而销毁主要依赖DisposableBeanAdapter这个类


AbstractAutowireCapableBeanFactory 的入口处,doCreateBean的核心代码如下,其中包含了实例化、设置属性值、初始化Bean以及注册销毁回调的几个核心方法。

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {//实例化 Bean。BeanWrapper instanceWrapper = null;if (mbd.isSingleton()) {instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);}if (instanceWrapper == null) {instanceWrapper = createBeanInstance(beanName, mbd, args);}Object bean = instanceWrapper.getWrappedInstance();Class<?> beanType = instanceWrapper.getWrappedClass();if (beanType != NullBean.class) {mbd.resolvedTargetType = beanType;}//..............................................//初始化 Bean 实例。Object exposedObject = bean;try {//设置属性值populateBean(beanName, mbd, instanceWrapper);//初始化BeanexposedObject = initializeBean(beanName, exposedObject, mbd);}//......................................//注册Bean的销毁回调。try {registerDisposableBeanIfNecessary(beanName, bean, mbd);}catch (BeanDefinitionValidationException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);}return exposedObject;}

  而DisposableBeanAdapter的destory方法的核心内容如下

@Overridepublic void destroy() {//...........................if (this.invokeDisposableBean) {//........................try {((DisposableBean) this.bean).destroy();}//.............................//判断是否自定义了销毁方法else if (this.destroyMethods != null) {//遍历每个销毁方法并调用for (Method destroyMethod : this.destroyMethods) {invokeCustomDestroyMethod(destroyMethod);}}else if (this.destroyMethodNames != null) {//遍历每个销毁方法名称并通过方法名称调用for (String destroyMethodName : this.destroyMethodNames) {Method destroyMethod = determineDestroyMethod(destroyMethodName);if (destroyMethod != null) {invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(destroyMethod, this.bean.getClass()));}}}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/580780.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

视频压缩不影响画质简单方法,一分钟搞定!

很多朋友在处理视频的时候都会遇到视频过大的问题&#xff0c;想要压缩视频的同时不影响画质&#xff0c;简单的方法有两种。一种是用专业的压缩软件&#xff0c;在压缩的时候设置一个合适的压缩比例&#xff0c;压缩大小的同时保持清晰度&#xff0c;也能提高压缩率&#xff0…

学习自定义【Spring Boot Starter】这一篇就够了

目录 1. starter介绍2. starter原理2-1. 起步依赖2-2. 自动配置基于Java代码的Bean配置自动配置的条件依赖Bean参数获取Bean的发现Bean的加载自动配置总结 3. 自定义starter案例3-1. 开发starter3-2. 使用starter 1. starter介绍 我们知道Spring Boot大大简化了项目初始搭建以…

取消终端代理

1. 查看当前的代理设置 首先&#xff0c;你可以使用 echo 命令来检查当前是否设置了代理环境变量。在终端中执行以下命令&#xff1a; echo $http_proxy echo $https_proxy如果这些命令返回了代理地址或者相关的信息&#xff0c;那就意味着代理已经设置。 2. 取消代理设置 …

C语言之进制转换

C语言之进制转换 一、引言二、十进制与二进制、八进制、十六进制三、二进制与八进制、十六进制四、八进制与十六进制 一、引言 在C语言中&#xff0c;经常使用的整数的进制有十进制、二进制、十六进制&#xff08;在C语言中以0x或0X为前缀&#xff09;、八进制&#xff08;在C…

SpringBoot实用开发(三)-- Redis提供API接口 -- StringRedisTemplate

引言: 由于redis内部不提供java对象的存储格式,因此当操作的数据以对象的形式存在时,会进行转码,转换成字符串格式后进行操作。为了方便开发者使用基于字符串为数据的操作,springboot整合redis时提供了专用的API接口StringRedisTemplate,你可以理解为这是RedisTe…

自动驾驶代客泊车AVP路径规划详细设计

目 录 1 背景... 1 2 名词解释... 2 3 路径规划及控制总体设计&#xff08;SMPC&#xff09;... 3 4 路径规划及控制详细设计... 4 4.1 决策场景... 4 4.2 接口定义... 4 4.2.1 目标车道线的巡航场景... 4 4.2.2 目标车道线与动态障碍物的混合场景... 4 4.2.3 垂直泊车…

uniapp 创建项目

uniapp 是一款基于 Vue 框架的跨平台应用开发框架。 创建 uniapp 项目 一、打开 HbuilderX 编辑器&#xff0c;点击新建项目。 二、选择 uniapp 项目、自定义项目名称、选择默认模板、选择 Vue 版本、点击创建。 三、这样 uniapp 项目就创建完毕啦&#xff01; 运行 uniapp …

2023年秋季学期《算法分析与设计》练习16 OJ-1425 算法分析与设计练习16,使用python

N皇后问题 使用回溯法求解N后问题。 输入 皇后的个数。 输出 每一种方案及总方案数。 样例输入 Copy 4 样例输出 Copy 0 1 0 0 0 0 0 2 3 0 0 0 0 0 4 0 ---------------- 0 0 1 0 2 0 0 0 0 0 0 3 0 4 0 0 ---------------- 总方案数为&#xff1a;2 def dfs(row, n)…

安防视频监控系统EasyCVR实现H.265视频在3秒内起播的注意事项

可视化云监控平台/安防视频监控系统EasyCVR视频综合管理平台&#xff0c;采用了开放式的网络结构&#xff0c;可以提供实时远程视频监控、视频录像、录像回放与存储、告警、语音对讲、云台控制、平台级联、磁盘阵列存储、视频集中存储、云存储等丰富的视频能力&#xff0c;同时…

spdlog中的异步日志方案

日志方案 同步日志方案&#xff1a;立即输出日志记录的方案才能继续执行其他任务。 异步日志方案&#xff1a;先抛出一个日志记录的任务到某个地方&#xff0c;不马上执行打印也不影响往下执行其他任务。 二者关键区别是产生日志记录并调用相关的日志任务接口之后&#xff0…

若依报500异常,只有前端没有后端

1.在vue.config.js中target的网址为https://vue.ruoyi.vip, process.env.VUE_APP_BASE_API]: { target: https://vue.ruoyi.vip,}2.pathRewrite单引号中加入 /prod-api pathRewrite: { ^ process.env.VUE_APP_BASE_API]: /prod-api3.在.env.development中变更 VUE_APP_BASE…

【Python】Python 输出中文乱码问题解决

Python 中文乱码的解决方法 1. 理解编码和解码 Python的字符编码遵循Unicode标准,但在不同的操作系统和编程环境下会有不同的默认字符编码,导致中文输出出现乱码等问题。解决中文输出乱码的问题,需要先理解编码和解码的概念。 编码: 把字符转换成字节序列的过程。因为计算…

CMMI认证办理流程以及需要参与的人员

CMMI&#xff08;Capability Maturity Model Integration&#xff09;认证是衡量软件企业过程管理成熟度的一种标准&#xff0c;它由美国卡内基-梅隆大学软件工程研究中心与美国国防部共同开发。CMMI认证分为五个等级&#xff0c;从低到高依次为1级到5级。以下是办理CMMI证书的…

数据结构-汇总

时间复杂度-汇总 一、二叉树 1、树的结构-初期 2、二叉树的分类-平衡树-红黑树 二叉树的旋转-LL\RR\RL\LR 3、二叉树的旋转-高级一步到位 4、红黑树特征、删除、插入

test mock-01-什么是 mock? Mockito/EasyMock/PowerMock/JMockit/Spock mock 框架对比

拓展阅读 test 之 jmockit-01-overview jmockit-01-test 之 jmockit 入门使用案例 mockito-01-overview mockito 简介及入门使用 PowerMock Mock Server ChaosBlade-01-测试混沌工程平台整体介绍 jvm-sandbox 入门简介 单元测试中的 mock 单元测试是一种验证代码单元&…

K8S网络类型

k8s的网络类型 k8s的通信模式 1 pod内部之间容器与容器之间的通信&#xff0c;在同一个pod中容器是共享资源和网络&#xff0c;使用同一个网络命名空间&#xff0c;可以直接通信 2 同一个node节点之内&#xff0c;不同pod之间的通信&#xff0c;每个pod都有一个全局的真实ip地…

AI 领域代币市场趋势:探索最热门投资领域的前沿动向

作者&#xff1a;lesleyfootprint.network 数据源&#xff1a;Token Sector Dashboard ChatGPT 的热潮点燃了 AI 领域&#xff0c;AI 与区块链技术的融合成为市场关注的焦点。因为区块链的一个显著特征是它能够在链上安全地存储大量数据&#xff0c;这与 AI 模型对数据的密集…

mysql面试题:索引(B+树、聚集索引、二级索引、回表查询、覆盖索引、超大分页查询、索引创建原则)

索引 概念 索引&#xff08;index&#xff09;是帮助MySQL高效获取数据的数据结构(有序)。在数据之外&#xff0c;数据库系统还维护着满足特定查找算法的数据结构**&#xff08;B树&#xff09;**&#xff0c;这些数据结构以某种方式引用&#xff08;指向&#xff09;数据&am…

安装虚拟机在虚拟机里面安装WindowsServer2012与步骤

目录 一、VMware介绍 1.1、概念讲解 1.2、VMware虚拟机的安装讲解 1.3、具体操作步骤 二、虚拟机安装WindowsServer2012演示 2.1、在虚拟机里配置具体步骤 (相当于制作启动U盘) 2.2、安装windows server2012步骤演示 三、Windows Server2012激活步骤演示 四、思维导…

golang并发安全-sync.map

sync.map解决的问题 golang 原生map是存在并发读写的问题&#xff0c;在并发读写时候会抛出异常 func main() {mT : make(map[int]int)g1 : []int{1, 2, 3, 4, 5, 6}g2 : []int{4, 5, 6, 7, 8, 9}go func() {for i : range g1 {mT[i] i}}()go func() {for i : range g2 {mT[…