谈谈你对Spring Bean生命周期的理解【面试】
前言
面试中经常会被问到Spring Bean的生命周期,有些人说记不住,看了一遍源码也是云里雾里的,那是因为只看理论,没有自己实践,如果自己亲自写代码验证一下,不管是对Spring的宏观感受,还是微观的感觉,都会有进一步的理解。
本篇会先展示代码的结果,后面再进行分析,代码的获取地址:码云地址
1、测试结果演示
Spring容器初始化===========================
五月 16, 2020 3:18:44 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@13b6d03: startup date [Sat May 16 15:18:44 CST 2020]; root of context hierarchy
五月 16, 2020 3:18:45 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationContext.xml]
【步骤1】执行Bean的无参构造函数
【步骤2】执行Bean的set方法,设置name属性值:coolsummermoon
【步骤2】执行Bean的set方法,设置sex属性值:man
【步骤3】执行BeanNameAware中setBeanName方法,beanName值:iocBeanLifeService
【步骤4】执行BeanClassLoaderAware中setBeanClassLoader,ClassLoader的name = sun.misc.Launcher$AppClassLoader
【步骤5】执行BeanFactoryAware中setBeanFactory,beanFactory中是否包含IocBeanLifeService:true
【步骤6】执行EnvironmentAware的setEnvironment方法
【步骤7】执行ResourceLoaderAware的setResourceLoader方法,Resource File Name=applicationContext.xml
【步骤8】执行ApplicationEventPublisherAware中setApplicationEventPublisher方法
【步骤9】执行ApplicationContextAware的setApplicationContext方法,Bean Definition Names=[iocBeanLifeService, org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#0, ioc.CustomerBeanPostProcessor#0]
【步骤10】执行BeanPostProcessor中postProcessBeforeInitialization方法,beanName=iocBeanLifeService
【步骤11】执行PostConstruct注解标注的方法
【步骤12】执行InitializingBean的afterPropertiesSet方法
【步骤13】执行配置的init-method
【步骤14】执行BeanPostProcessor的postProcessAfterInitialization方法,beanName=iocBeanLifeService
五月 16, 2020 3:18:45 下午 org.springframework.context.support.AbstractApplicationContext doClose
信息: Closing org.springframework.context.support.ClassPathXmlApplicationContext@13b6d03: startup date [Sat May 16 15:18:44 CST 2020]; root of context hierarchy
Spring容器初始化完毕========================
从容器中获取Bean
IocBeanLifeService{name='coolsummermoon', sex='man'}
Spring容器准备关闭==========================
【步骤15】执行preDestroy注解标注的方法
【步骤16】执行DisposableBean接口的destroy方法
【步骤17】执行配置的destroy-method
Spring容器完成关闭===========================Process finished with exit code 0
2、结果分析
2.1、上面的结果,我们可以初步分四个阶段:
- Bean的实例化阶段
- Bean的设置属性阶段
- Bean的 初始化阶段
- Bean的销毁阶段
2.2、在初始化阶段,有个特别重要的接口BeanPostProcessor,在初始化前、后调用:
2.3、在设置属性阶段后,postProcessBeforeInitialization方法执行前,会执行很多Aware类型的接口,这种类型接口作用是加载资源到Spring容器中,Aware前面的名字就对应哪种资源,依次加载的是:
- BeanNameAware
- BeanClassLoaderAware
- BeanFactoryAware
- EnvironmentAware
- ResourceLoaderAware
- ApplicationEventPublisherAware
- ApplicationContextAware
看到这里应该明白BeanFactory和ApplicationContext的区别了:
BeanFactoryAware之前加载的资源都是公共的。BeanFactoryAware后面加载的资源都是ApplicationContext独有的。
2.4、初始化方式有三个,分别是:
- InitializingBean的afterPropertiesSet方法
- PostConstruct注解标注的方法
- 配置的init-method
上面的三个方法效果都是一样的,开发中选择其中一种方式就行,一般我们选择2、3方法中的一个。
2.5、容器销毁的方式有三个,分别是:
- preDestroy注解标注的方法
- DisposableBean接口的destroy方法
- 配置的destroy-method
上面的三个方法效果都是一样的,开发中选择其中一种方式就行,一般我们选择1、3方法中的一个。
3、总结
综合前面的代码和分析,现在我们用大白话描述下:
- Bean容器找到Spring配置文件中Bean的定义;
- Bean容器利用java 反射机制实例化Bean;
- Bean容器为实例化的Bean设置属性值;
- 如果Bean实现了BeanNameAware接口,则执行setBeanName方法;
- 如果Bean实现了BeanClassLoaderAware接口,则执行setBeanClassLoader方法;
- 如果Bean实现了BeanFactoryAware接口,则执行setBeanFactory方法;
- 如果 ……真的,到这我经常忘记,但前面三个Aware接口肯定能记住;
- 如果Bean实现了ApplicationContextAware接口,则执行setApplicationContext方法;
- 如果加载了BeanPostProcessor相关实现类,则执行postProcessBeforeInitialization方法;
- 如果Bean定义初始化方法(PostConstruct注解、配置init-method、实现了InitializingBean接口),则执行定义的初始化方法;
- 如果加载了BeanPostProcessor相关实现类,则执行postProcessAfterInitialization方法;
- 当要销毁这个Bean时,如果自定义了销毁方法(PreDestroy注解、配置destroy-method、实现了DisposableBean接口),则执行定义的销毁方法。
结束语
留一个思考题:作用域是单例和原型的Bean,Spring对其生命周期是如何管理的?
欢迎大家关注下方微信公众号,我们一起讨论技术、理财方面的知识,解决生活中遇到的问题。
谈谈你对Spring Bean生命周期的理解【面试】相关推荐
- Spring5源码 - 07 Spring Bean 生命周期流程 源码解读02
文章目录 Pre 通俗流程 finishBeanFactoryInitialization Pre Spring5源码 - 06 Spring Bean 生命周期流程 概述 01 接上文 通俗流程 下 ...
- Spring Bean默认配置为单实例 Spring Bean生命周期
2019独角兽企业重金招聘Python工程师标准>>> Spring 的Bean默认的是单例的. 如果不想单例需要如下配置: <bean id="user" ...
- Spring框架:三种Spring Bean生命周期技术
当使用术语"生命周期"时,Spring的家伙指的是您的bean的构造和破坏,通常这与Spring Context的构造和破坏有关. 在某些情况下,Bean生命周期的管理不是一件容易 ...
- Spring Bean生命周期: Bean的实例化
[Spring Bean 生命周期系列]传送门 1.Spring Bean生命周期: Bean元信息的配置与解析阶段 2.Spring Bean生命周期: Bean的注册 3.Spring Bean生 ...
- Spring Bean生命周期过程
Spring Bean生命周期过程 Spring Bean生命周期指的是Bean加载Spring容器的过程,单例的Bean与多例的Bean加载过程是不一样的.这里指的是单例Bean的加载过程. 图:S ...
- Spring Bean 生命周期之“我从哪里来”?懂得这个很重要
Spring bean 的生命周期很容易理解.实例化 bean 时,可能需要执行一些初始化以使其进入可用 (Ready for Use)状态.类似地,当不再需要 bean 并将其从容器中移除时,可能需 ...
- Spring Bean生命周期:Bean的初始化阶段
[Spring Bean 生命周期系列]传送门 1.Spring Bean生命周期: Bean元信息的配置与解析阶段 2.Spring Bean生命周期: Bean的注册 3.Spring Bean生 ...
- Spring5源码 - 06 Spring Bean 生命周期流程 概述 01
文章目录 Bean生命周期概述 Demo finishBeanFactoryInitialization(beanFactory) 核心流程 Bean生命周期概述 说到Spring Bean的生命周期 ...
- spring bean生命周期_Spring中bean的生命周期和扩展点有哪些?
前言 今天和大家分享一下Spring中Bean的生命周期的一些知识.先来说一下什么是生命周期吧,生命周期从其语义上理解就是一个对象从产生到销毁的整个过程,之所以把这个过程称为生命周期是因为其就像一个生 ...
最新文章
- [JZOJ6075]【GDOI2019模拟2019.3.20】桥【DP】【线段树】
- python填写excel-python读写Excel
- 文本特征选择 java代码_文本分类入门(十)特征选择算法之开方检验
- 科大星云诗社动态20210224
- aircv 安装_Python 通过截图匹配原图中的位置(opencv)实例
- ssl1615-Frogger【图论,最小生成树,并查集】
- Flask中的session操作
- 在python中可以使用for作为变量名对吗_python能用一个变量的值作为另一个变量的变量名吗?...
- Gitee 轻量级 PR ——参与开源贡献,原来就是举手之劳的事
- Windows API 进程状态信息函数
- 从此,懂一点CDMA
- Python基础——timeit模块
- JavaWeb开发Servlet学习
- 学生a3制图标题栏尺寸手绘_机械制图基础知识学习,如何画好一张零件图?
- Access数据库实用教程-----创建更新查询
- Redis官方中文翻译系列 - Redis文档
- 数据库 求闭包、求候选码、范式转换、最小依赖集、无损分解及保持函数依赖
- 微信小程序实现图片预览(闭眼cv)
- 电脑usb蓝牙的使用
- 平板电脑性价比排行2022