如何理解 SpringBoot 的生命周期

chatgpt/2023/10/4 8:40:01

生命周期,就是从诞生到死亡的一个过程。Spring 中 bean 也是如此。在 Spring 中的 ConfigurableApplicationContext 的 refresh 开始直到一个 bean 可以被正常使用,中间经历了一系列初始化操作;而在其 close 后又经历了一系列销毁操作,这被称之为 Spring 中 bean 的生命周期。

周期

Spring 中的 bean 经历了以下阶段:

bean的生命阶段

其中红色的框不属于 Spring 来管理了。

实例化

实例化就是 Spring 通过反射来调用构造方法来实例化一个对象。

初始化

Spring 的初始化有两种方式,一种是实现 InitializingBean 接口,另一种是在一个方法上面加上 @PostConstruct 注解表示这是一个初始化方法。

销毁

Spring 的销毁对象的方式也有两种,一种是实现 DisposableBean,另一种是在一个方法上加 @PreDestroy 注解;和 初始化 的两种方式相对应。

顺序

具体顺序是如何,我们用一段代码就可以看到。

// NormalEntity.java 这是一个将往 Spring 中注入的类
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;public class NormalEntity implements InitializingBean, DisposableBean {public NormalEntity() {System.out.println("NormalEntity constructor...");}@PostConstructpublic void init() {System.out.println("NormalEntity PostConstruct");}@PreDestroypublic void preDestroy() {System.out.println("NormalEntity preDestroy");}@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("NormalEntity afterPropertiesSet");}@Overridepublic void destroy() throws Exception {System.out.println("NormalEntity destroy");}
}
// MainConfig.java
import org.springframework.context.annotation.Bean;public class MainConfig {@Beanpublic NormalEntity normalEntity() {return new NormalEntity();}
}
// MainTest.java 这里是启动类
import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class MainTest {public static void main(String[] args) {AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);NormalEntity bean = applicationContext.getBean(NormalEntity.class);System.out.println(bean);// 这里使用的是 AnnotationConfigApplicationContext,需要手动调用 close// 如果是 SpringBoot 项目,会自动注册 shutdown hook,里面调用了 close 方法applicationContext.close();}
}

会看到控制台打印出了结果,也展示了调用顺序:

NormalEntity constructor...
NormalEntity PostConstruct
NormalEntity afterPropertiesSet
NormalEntity preDestroy
NormalEntity destroy

代码的调用

在构造方法下一个断点,就可以根据调用栈知道调用路径了。

下面简要说明几处。

AbstractApplicationContext#finishBeanFactoryInitialization(ConfigurableListableBeanFactory)

实例化所有剩下的非懒加载的单例bean
AbstractApplicationContext#refresh 方法的倒数第二步调用了此方法来实例化容器中所有的非懒加载的bean(懒加载的肯定是用到的时候再实例化),这里就最终可以到AbstractBeanFactory#doGetBean(String, Class<T>, Object[], boolean)里面的getSingleton(String, ObjectFactory<?>),那最终其实就是调用参数ObjectFactory<?>提供的createBean(String, RootBeanDefinition, Object[])方法。

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean(String, RootBeanDefinition, Object[])

  1. 调用createBeanInstance(String, RootBeanDefinition, Object[])方法来使用构造方法实例化对象;
  2. 在下面的applyMergedBeanDefinitionPostProcessors(RootBeanDefinition, Class<?>, String)中使用BeanPostProcessor调用有注解的初始化方法;
  3. initializeBean(String, Object, RootBeanDefinition)方法中调用了实现了InitializingBean接口的afterPropertiesSet方法

经历以上三步骤,bean的初始化完成。

同时如果想要知道Spring的bean在销毁时做了什么,可以在另外两个销毁方法下断点,就可以知道了。

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

如若内容造成侵权/违法违规/事实不符,请联系郑州代理记账网进行投诉反馈,一经查实,立即删除!

相关文章

在OK3588板卡上部署模型实现人工智能OCR应用

一、主机模型转换 我们依旧采用FastDeploy来部署应用深度学习模型到OK3588板卡上 进入主机Ubuntu的虚拟环境 conda activate ok3588 安装rknn-toolkit2&#xff08;该工具不能在OK3588板卡上完成模型转换&#xff09; git clone https://github.com/rockchip-linux/rknn-to…

Ansible的脚本 --- playbook 剧本

文章目录 一、playbook剧本的组成创建剧本运行playbook二、定义、引用变量三、指定远程主机sudo切换用户四、when条件判断五、迭代Templates 模块tags 模块 一、playbook剧本的组成 playbooks 本身由以下各部分组成 &#xff08;1&#xff09;Tasks&#xff1a;任务&#xff0…

发现的宝藏开源软件

1.华夏erp https://github.com/jishenghua/jshERP 2.s2b2c商城 后端 lilishop商城 电商 java商城系统: lilishop商城基于SpringBoot 全端开源 电商商城系统 支持小程序商城 H5商城 APP商城 PC商城 。支持业务模式包含 O2O商城 B2B商城 多语言商城 跨境电商 B2B2C商城 F2B2C商…

github使用笔记及git协作常用命令

1.Github有一个主库,每个人自己也有一个库,称为分支。 2.Github的协作流程:先从主库fork出自己的分支, 然后进行代码的修改等操作, 操作完之后从本地库上推到自己的服务器分支,然后 服务器分支Pull Request到 主库。 3.本地仓库由git维护的三棵“树"组成:第1个…

mysql的json处理

写在前面 需要注意&#xff0c;5.7以上版本才支持&#xff0c;但如果是生产环境需要使用的话&#xff0c;尽量使用8.0版本&#xff0c;因为8.0版本对json处理做了比较大的性能优化。你你可以使用select version();来查看版本信息。 本文看下MySQL的json处理。在正式开始让我们先…

pytorch学习——正则化技术——权重衰减

一、概念介绍 权重衰减&#xff08;Weight Decay&#xff09;是一种常用的正则化技术&#xff0c;它通过在损失函数中添加一个惩罚项来限制模型的复杂度&#xff0c;从而防止过拟合。 在训练参数化机器学习模型时&#xff0c; 权重衰减&#xff08;weight decay&#xff09;是…

刷题 41-45

四十一、移除元素 示例 1&#xff1a; 输入&#xff1a;nums [3,2,2,3], val 3 输出&#xff1a;2, nums [2,2] 解释&#xff1a;函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。例如&#xff0c;函数返回的新长度为 2 …
推荐文章