Java面试题:浅谈Spring Bean的生命周期
摘要:如果熟悉Spring 中 Bean的生命周期,可以加深对Spring的认知,故综述一下Bean的生命周期。
前言
Spring中Bean的生命周期是找工作的时候会被问到的高频面试题,主要用于考察应聘者对Spring是否熟悉,工作中很少用到其中的内容。
配置在Spring中的Bean在Spring容器中从加载到销毁会经历哪些过程呢?如果实现一些特定的Spring接口,这些特定接口的方法会在什么时候被调用呢?
Bean初始化入口:以Spring Boot项目为例,在项目启动的时候,SpringApplication的run方法会调用函数refreshContext(ApplicationContext applicationContext),此函数最终调用 AbstractApplicationContext 类的refresh()方法以刷新容器,创建Bean。refresh()方法源码如下,如果为了面试,可以跳过(嘻嘻):
/** Synchronization monitor for the "refresh" and "destroy". */
private final Object startupShutdownMonitor = new Object();
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 设置Spring容器的启动时间,撤销关闭状态,开启活跃状态
// Prepare this context for refreshing.
prepareRefresh();
// 得到BeanFactory
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 给BeanFactory设置一些属性
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// 后置处理BeanFactory
postProcessBeanFactory(beanFactory);
// 注册并调用BeanFactoryPostProcessor后置处理器
// 其中ConfigurationClassPostProcessor这个后置处理器会扫描Bean并且注册到容器中
//这个方法做了很多事,Spring IOC容器初始化中的资源定位、BeanDefinition载入和解析、BeanDefinition注册都是这个方法完成的
invokeBeanFactoryPostProcessors(beanFactory);
// 注册BeanPostProcessor后置处理器,这里的后置处理器在下方实例化Bean方法中会用到
registerBeanPostProcessors(beanFactory);
initMessageSource();
// 初始化ApplicationEventMulticaster
initApplicationEventMulticaster();
//创建tomcat启动了Tomcat的Server、Service、Container、Engine、Realm、Pipeline、Value、MapperListerner
onRefresh();
// 注册监听器
registerListeners();
// 实例化非懒加载的Bean
finishBeanFactoryInitialization(beanFactory);
// 启动tomcat的Connector
finishRefresh();
} catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
} finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
Bean的生命周期
一个Bean从创建到销毁,如果是用BeanFactory来生成和管理Bean的话,主要会经历四个过程:实例化 -> 属性赋值 -> 初始化 -> 销毁。
- 实例化 Instantiation
- 属性赋值 Populate
- 初始化 Initialization
- 销毁 Destruction
spring Bean加载的过程主要就是执行AbstractApplicationContext类中的refresh方法。完整生命周期如下图所示:

Bean实例化
也就是我们常说的new,调用Bean的构造函数或者工厂方法。属性赋值
对Bean的成员变量赋值。使用依赖注入,Spring按照Bean定义信息配置Bean所有属性。BeanNameAware的setBeanName()
如果Bean类有实现org.springframework.beans.BeanNameAware接口,工厂调用Bean的setBeanName()方法传递Bean的ID。BeanFactoryAware的setBeanFactory()
如果Bean类有实现org.springframework.beans.factory.BeanFactoryAware接口,工厂调用setBeanFactory()方法传入工厂自身。实现了ApplicationContextAware接口
使用ApplicationContext来生成并管理Bean的话,才有此步;否则,没有。
如果这个Bean已经实现了ApplicationContextAware接口,会调用setApplicationContext(ApplicationContext)方法,传入Spring上下文(同样这个方式也可以实现上一步的内容,但比上一步更好,因为ApplicationContext是BeanFactory的子接口,有更多的实现方法);BeanPostProcessors的ProcessBeforeInitialization()
如果有org.springframework.beans.factory.config.BeanPostProcessors和Bean关联,那么其postProcessBeforeInitialization()方法将被将被调用。initializingBean的afterPropertiesSet():
如果Bean类已实现org.springframework.beans.factory.InitializingBean接口,则执行他的afterProPertiesSet()方法。Bean定义文件中定义init-method
如果在Bean定义文件中使用“init-method”属性设定方法名称,如下:
<bean id="demoBean" class="com.yangsq.bean.DemoBean" init-method="initMethod">
.......
</bean>
则会执行initMethod()方法,注意,这个方法是不带参数的。BeanPostProcessors的ProcessaAfterInitialization()
容器中如果有实现org.springframework.beans.factory.BeanPostProcessors接口的实例,则Bean在初始化之前都会执行这个实例的processAfterInitialization()方法。Bean处于可以使用的状态。
此时,Bean已经可以被应用系统使用,并且将保留在BeanFactory中直到它不再被使用。Spring容器关闭。
下面介绍销毁流程。DisposableBean的destroy()
容器关闭时,如果Bean类实现了org.springframework.beans.factory.DisposableBean接口,则执行它的destroy()方法。Bean定义文件中定义destroy-method
在容器关闭时,可以在Bean定义文件中使用"destroy-method"属性设定方法名称。例如:
<bean id="demoBean" class="com.yangsq.bean.DemoBean" destory-method="destroyMethod">
.......
</bean>
这时会执行destroyMethod()方法,注意,这个方法是不带参数的。
小结
在Spring框架中,一旦把一个bean纳入到Spring IoC容器之中,这个bean的生命周期就会交由容器进行管理,一般担当管理者角色的是BeanFactory或ApplicationContext。认识一下Bean的生命周期活动,对更好的利用它有很大的帮助。
Reference
- https://blog.csdn.net/weixin_34174105/article/details/85739351
- https://www.cnblogs.com/whuthxb/p/9385761.html
- https://blog.csdn.net/jy02268879/article/details/87879246
Java面试题:浅谈Spring Bean的生命周期的更多相关文章
- Spring Bean的生命周期相关博客
最近得面试题一直 问 Spring 得生命周期,鉴于自己还未阅读过源码 所以只能是自己 背一波了.属实不懂硬背得作用,但是无奈被各位面试官打败了.等以后有时间了 一定要阅读几遍spring的 源码 有 ...
- Spring Bean的生命周期(非常详细)
Spring作为当前Java最流行.最强大的轻量级框架,受到了程序员的热烈欢迎.准确的了解Spring Bean的生命周期是非常必要的.我们通常使用ApplicationContext作为Spring ...
- Spring Bean的生命周期,《Spring 实战》书中的官方说法
连着两天的面试 ,都问到了 Spring 的Bean的生命周期,其中还包括 昨晚一波阿里的电话面试.这里找到了Spring 实战中的官方说法.希望各位要面试的小伙伴记住,以后有可能,或者是有时间 去看 ...
- Spring Bean的生命周期详解(转)
Spring作为当前Java最流行.最强大的轻量级框架,受到了程序员的热烈欢迎.准确的了解Spring Bean的生命周期是非常必要的.我们通常使用ApplicationContext作为Spring ...
- Spring动态代理及Spring Bean的生命周期
数组添加值 public class DiTest { /** * 数组 */ private String [] arrays; /** * List:集合 */ private List<I ...
- Spring(三)--Spring bean的生命周期
Spring bean的生命周期 ApplicationContext Bean生命周期流程 1.需要的实体类 ackage com.xdf.bean; import org.springframew ...
- 第37讲 谈谈Spring Bean的生命周期和作用域
在企业应用软件开发中,Java 是毫无争议的主流语言,开放的 Java EE 规范和强大的开源框架功不可没,其中 Spring 毫无疑问已经成为企业软件开发的事实标准之一.今天这一讲,我将补充 Spr ...
- spring bean的生命周期
掌握好spring bean的生命周期,对spring的扩展大有帮助. spring bean的生命周期(推荐看) spring bean的生命周期
- Spring学习手札(四)谈谈Spring Bean的生命周期及作用域
在Spring中,那些组成应用程序的主体以及由Spring IoC容器所管理的对象,被称之为Bean.Bean与应用程序中其他对象(比如自己创建类)的区别就是,Bean是由IoC容器创建于销毁的.在S ...
- Spring原理系列一:Spring Bean的生命周期
一.前言 在日常开发中,spring极大地简化了我们日常的开发工作.spring为我们管理好bean, 我们拿来就用.但是我们不应该只停留在使用层面,深究spring内部的原理,才能在使用时融汇贯通. ...
随机推荐
- pnpm:无法加载文件 C:\Users\Five\AppData\Roaming\npm\pnpm.ps1 ,因为在此系统上禁止运行脚本
前言 重装完了电脑系统,运行pnpm 无法加载文件,pnpm -V也不行 解决方案 用管理员方式启动power shell 输入命令:set-ExecutionPolicy RemoteSigned ...
- 晶振测试仪GDS-80系列参数
晶振测试仪GDS-80系列 一.产品简介 晶振测试仪GDS-80系列是高性价比的晶振测试系统,采用网络分析技术,实现智能化测量,符合IEC-444标准.测量频率范围10KHz-200KHz,1MHz- ...
- Set Cover问题的贪心近似算法分析
问题描述 全集 \(U = \{ e_1, e_2, ... , e_n \}\) 被划分为一系列的子集 \(S = \{ S_1, S_2, ... , S_k \}\).且存在一个cost函数\( ...
- CentOS——磁盘分区
Centos7-磁盘分区磁盘层次结构–磁盘分区方法情况一:磁盘分区–磁盘小于2T fdisk情况二:磁盘分区–磁盘大于2T centos6:parted centos7:fdisk一.磁盘小于2T情况 ...
- docker也一直发展
docker也一直发展.但本答案仅仅作为向新人介绍docker的入门文章的话,在大方向上还是没问题的.本文仅仅是个docker入门介绍文章,用比较宏大的叙事来描述docker的面貌,如果想了解更细节或 ...
- 05 过拟合(over-fitting)与正则化(regularization)
1. 什么是Overfitting 我们希望神经网络模型能够找到数据集中的一般规律,从而帮助我们预测未知数据.这个过程是通过不断地迭代优化损失函数(也就是预测值和实际值的误差)而实现的.然而随着误差进 ...
- 网络设备开局配置生成器(第三次更新) QQ交流群:(4817315)
下载:链接: https://pan.baidu.com/s/1BIvh3u7VfbaQtBsUOjl1IA?pwd=kgtw 提取码: kgtw 网络设备开局配置生成器(SecureCRT vbs脚 ...
- Ant Design Pro 中 点击子菜单的时候,其他菜单不自动收起来
记录一波自己在这段时间碰到的一个Ant Design Pro 的坑: 每次点击菜单都会将其他菜单自动收起来,导致一系列的用户体验不佳. 设置defaultOpenAll: true后依然不管用 经过各 ...
- 谷歌SRE的7条原则
谷歌SRE的7条原则 拥抱合理的风险 最大化系统的稳定性不仅毫无意义,而且会适得其反.不切实际的可靠性目标限制了新功能交付给用户的速度,而且用户通常不会注意到极端的可用性(比如99.99999%),因 ...
- ADM3251E使用一段时间后损坏
使用ADM3251E导致CPU发热 - 参考链接: https://bbs.elecfans.com/jishu_1687010_1_1.html 笔者设计的电路板在解决RS232隔离通信的时采用了A ...