Spring Framework核心概念之Bean生命周期管理
Spring Bean的生命周期
Spring容器既Application或者WebApplication会在管理Bean的时候;为了尽可能的把自己内部的东西机制暴露出来给用户使用,所以在Bean创建的过程中加了很多机制,通过所谓的"处理器"Processor暴露出来,然后处理器都有自己的顺序,我们需要做的就是定义好处理器的逻辑,然后注册到Sprinhg容器中,Spring就会调用了。下面就是Spring管理Bean的生命周期图。


下面这张图描述的更为详细。

相关接口的分类
对于上面图看不懂不要着急因为你并不认识与生命周期相关的接口。Spring生命周期你可以理解为四个等级;每个等级中都用有相应的接口,实现其中某个接口或者将实现类注入到Sprng容器,容器就会在相应的时机调用其方法。详细信息可看下面的一个表格。
- 工厂后处理器接口方法
- 容器级生命周期接口方法
- Bean级生命周期接口方法
- Bean本身方法
| 分类 | 接口 | 调用时间 |
|---|---|---|
| 工厂后处理器接口 | BeanFactoryPostProcessor | 容器创建完毕,装配Bean源后立即调用 |
| 容器后处理器接口 | InstantiationAwareBeanPostProcessor | 分别在调用构造之前,注入属性之前,实例化完成时调用 |
| 容器后处理器接口 | BeanPostProcessor | 分别在Bean的初始化方法调用前后执行 |
| Bean级后置处理器接口 | BeanNameAware | 注入属性后调用 |
| Bean级后置处理器接口 | BeanFactoryAware | 注入属性后调用 |
| Bean级后置处理器接口 | InitializingBean | 在类本身的初始化方法之前调用其方法(本身也是初始化方法) |
| Bean级后置处理器接口 | DiposableBean | 在类本身的销毁方法执行之前调用其方法(本身也是销毁方法) |
| Bean本身方法 | init方法 | 在注入属性之后调用初始化方法 |
| Bean本身方法 | destroy方法 | 在关闭容器的时候进行销毁 |
测试SpringBean生命周期的Demo程序
本测试程序来自https://www.cnblogs.com/zrtqsk/p/3735273.html 我在这里说一下测试程序是如何测试SpringBean的生命周期的。首先将一个工厂后处理器 BeanFactoryPostProcessor接口实现注入容器,再将容器后处理器InstantiationAwareBeanPostProcessor和BeanPostProcessor注入容器,又在自定义Person实现了Bean级后处理器BeanNameAware,BeanFactoryAware,InitializingBean和DiposableBean接口的相关方法,最后就是在自定义的Person类中实现了其本身的init()方法和destroy()方法。
- 自定义Person类
public class Person implements BeanFactoryAware, BeanNameAware,
InitializingBean, DisposableBean {
private String name;
private String address;
private int phone;
private BeanFactory beanFactory;
private String beanName;
public Person() {
System.out.println("【构造器】调用Person的构造器实例化");
}
public String getName() {
return name;
}
public void setName(String name) {
System.out.println("【注入属性】注入属性name");
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
System.out.println("【注入属性】注入属性address");
this.address = address;
}
public int getPhone() {
return phone;
}
public void setPhone(int phone) {
System.out.println("【注入属性】注入属性phone");
this.phone = phone;
}
@Override
public String toString() {
return "Person [address=" + address + ", name=" + name + ", phone="
+ phone + "]";
}
// 这是BeanFactoryAware接口方法
@Override
public void setBeanFactory(BeanFactory arg0) throws BeansException {
System.out
.println("【BeanFactoryAware接口】调用BeanFactoryAware.setBeanFactory()");
this.beanFactory = arg0;
}
// 这是BeanNameAware接口方法
@Override
public void setBeanName(String arg0) {
System.out.println("【BeanNameAware接口】调用BeanNameAware.setBeanName()");
this.beanName = arg0;
}
// 这是InitializingBean接口方法
@Override
public void afterPropertiesSet() throws Exception {
System.out
.println("【InitializingBean接口】调用InitializingBean.afterPropertiesSet()");
}
// 这是DiposibleBean接口方法
@Override
public void destroy() throws Exception {
System.out.println("【DiposibleBean接口】调用DiposibleBean.destory()");
}
// 通过<bean>的init-method属性指定的初始化方法
public void myInit() {
System.out.println("【init-method】调用<bean>的init-method属性指定的初始化方法");
}
// 通过<bean>的destroy-method属性指定的初始化方法
public void myDestory() {
System.out.println("【destroy-method】调用<bean>的destroy-method属性指定的初始化方法");
}
}
- MyBeanPostProcessor (实现容器级别后置处理器)
public class MyBeanPostProcessor implements BeanPostProcessor {
public MyBeanPostProcessor() {
super();
System.out.println("这是BeanPostProcessor实现类构造器!!");
// TODO Auto-generated constructor stub
}
@Override
public Object postProcessAfterInitialization(Object arg0, String arg1)
throws BeansException {
System.out
.println("BeanPostProcessor接口方法postProcessAfterInitialization对属性进行更改!");
return arg0;
}
@Override
public Object postProcessBeforeInitialization(Object arg0, String arg1)
throws BeansException {
System.out
.println("BeanPostProcessor接口方法postProcessBeforeInitialization对属性进行更改!");
return arg0;
}
}
- MyInstantiationAwareBeanPostProcessor(实现容器级别后置处理器)
public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter {
public MyInstantiationAwareBeanPostProcessor() {
super();
System.out
.println("这是InstantiationAwareBeanPostProcessorAdapter实现类构造器!!");
}
// 接口方法、实例化Bean之前调用
@Override
public Object postProcessBeforeInstantiation(Class beanClass,
String beanName) throws BeansException {
System.out
.println("InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法");
return null;
}
// 接口方法、实例化Bean之后调用
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
System.out
.println("InstantiationAwareBeanPostProcessor调用postProcessAfterInitialization方法");
return bean;
}
// 接口方法、设置某个属性时调用
@Override
public PropertyValues postProcessPropertyValues(PropertyValues pvs,
PropertyDescriptor[] pds, Object bean, String beanName)
throws BeansException {
System.out
.println("InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法");
return pvs;
}
}
- MyBeanFactoryPostProcessor (实现容器级别后置处理器)
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
public MyBeanFactoryPostProcessor() {
super();
System.out.println("这是BeanFactoryPostProcessor实现类构造器!!");
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory arg0)
throws BeansException {
System.out
.println("BeanFactoryPostProcessor调用postProcessBeanFactory方法");
BeanDefinition bd = arg0.getBeanDefinition("person");
bd.getPropertyValues().addPropertyValue("phone", "110");
}
}
- 配置Spring的xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
<bean id="beanPostProcessor" class="com.jimisun.learnspringboot.web.MyBeanPostProcessor">
</bean>
<bean id="instantiationAwareBeanPostProcessor"
class="com.jimisun.learnspringboot.web.MyInstantiationAwareBeanPostProcessor">
</bean>
<bean id="beanFactoryPostProcessor" class="com.jimisun.learnspringboot.web.MyBeanFactoryPostProcessor">
</bean>
<bean id="person" class="com.jimisun.learnspringboot.web.Person" init-method="myInit"
destroy-method="myDestory" scope="singleton" p:name="张三" p:address="广州"
p:phone="15900000000"/>
</beans>
- Main方法执行测试
public class Main {
public static void main(String[] args) {
System.out.println("现在开始初始化容器");
ApplicationContext factory = new ClassPathXmlApplicationContext("bens.xml");
System.out.println("容器初始化成功");
//得到Preson,并使用
Person person = factory.getBean("person",Person.class);
System.out.println(person);
System.out.println("现在开始关闭容器!");
((ClassPathXmlApplicationContext)factory).registerShutdownHook();
}
}
- 测试结果(我对Main方法执行结果做了格式化,方便参照)

LOGGER测试:现在开始初始化容器
【工厂构造】这是BeanFactoryPostProcessor实现类构造器!!
【工厂方法】BeanFactoryPostProcessor调用postProcessBeanFactory方法
【容器构造】这是BeanPostProcessor实现类构造器!!
【容器构造】这是InstantiationAwareBeanPostProcessorAdapter实现类构造器!!
【容器方法】InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法
【类构造】调用Person的构造器实例化
【容器方法】InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法
【类注入属性】注入属性address
【类注入属性】注入属性name
【类注入属性】注入属性phone
【Bean方法:BeanNameAware接口】调用BeanNameAware.setBeanName()
【Bean方法:BeanFactoryAware接口】调用BeanFactoryAware.setBeanFactory()
【容器方法】BeanPostProcessor接口方法postProcessBeforeInitialization对属性进行更改!
【Bean方法:InitializingBean接口】调用InitializingBean.afterPropertiesSet()
【自身方法:init-method】调用<bean>的init-method属性指定的初始化方法
【容器方法】BeanPostProcessor接口方法postProcessAfterInitialization对属性进行更改!
【容器方法】InstantiationAwareBeanPostProcessor调用postProcessAfterInitialization方法
LOGGER测试:容器初始化成功
Person [address=广州, name=张三, phone=110]
LOGGER测试:现在开始关闭容器!
【Bean级别:DiposibleBean接口】调用DiposibleBean.destory()
【自身方法:destroy-method】调用<bean>的destroy-method属性指定的初始化方法
将Demo代码的执行结果与上述表中的执行时机进行对比,看看执行时机是否正确,
小结
理解透彻Spring Bean的生命周期对开发中可以解决比较棘手的问题,对于深入学习Spring Framework框架这是必须要掌握的知识,所以可以多看两遍。
该教程所属Java工程师之Spring Framework深度剖析专栏,本系列相关博文目录 Java工程师之Spring Framework深度剖析专栏
Spring Framework核心概念之Bean生命周期管理的更多相关文章
- 【Spring Framework】Spring IOC详解及Bean生命周期详细过程
Spring IOC 首先,在此之前,我们就必须先知道什么是ioc,ioc叫做控制反转,也可以称为依赖注入(DI),实际上依赖注入是ioc的另一种说法, 1.谁控制谁?: 在以前,对象的创建和销毁都是 ...
- 从启动日志看Spring IOC的初始化和Bean生命周期
一.Tomcat中启动IoC容器的日志 启动Tomcat等容器时,控制台每次都打印出一些日志. 最近刚好在研究Spring源码,所以换个角度,从启动日志来简单的看看Spring的初始化过程! 以下是T ...
- spring bean生命周期管理--转
Life Cycle Management of a Spring Bean 原文地址:http://javabeat.net/life-cycle-management-of-a-spring-be ...
- Spring-IOC bean 生命周期之 Lifecycle 钩子
Lifecycle callbacks Initialization callbacks.Destruction callbacks 要与容器的bean生命周期管理交互,即容器在启动后和容器在销毁前对 ...
- beanFactory 设计模式 Bean 生命周期的胡言乱语,哈哈
写在前面的话 适用读者:有一定经验的,本文不适合初学者,因为可能不能理解我在说什么 文章思路:不会一开始就像别的博客文章那样,Bean 的生命周期,源码解读(给你贴一大堆的源码).个人觉得应该由问题驱 ...
- beanFactory 设计模式 Bean 生命周期
写在前面的话 适用读者:有一定经验的,本文不适合初学者,因为可能不能理解我在说什么 文章思路:不会一开始就像别的博客文章那样,Bean 的生命周期,源码解读(给你贴一大堆的源码).个人觉得应该由问题驱 ...
- Elasticsearch 快照生命周期管理 (SLM) 实战指南
文章转载自:https://mp.weixin.qq.com/s/PSfgPJc4dKN2pOZd0Y02wA 1.Elasticsearch 保证高可用性的方式 Elasticsearch 保证集群 ...
- JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(6):Spring IOC容器学习(概念、作用、Bean生命周期)
一.IOC控制反转概念 控制反转(IOC)是一种通过描述(在Java中可以是XML或者是注解)并通过第三方去生产或获取特定对象的方式. 主动创建模式,责任在于开发者,而在被动模式下,责任归于Ioc容器 ...
- spring(二、bean生命周期、用到的设计模式、常用注解)
spring(二.bean生命周期.用到的设计模式.常用注解) Spring作为当前Java最流行.最强大的轻量级框架,受到了程序员的热烈欢迎.准确的了解Spring Bean的生命周期是非常必要的. ...
随机推荐
- Reg命令使用详解 批处理操作注册表必备
首先要说明:编辑注册表不当可能会严重损坏您的系统.在更改注册表之前,应备份计算机上任何有价值的数据 只有在别无选择的情况下,才直接编辑注册表.注册表编辑器会忽略标准的安全措施,从而使得这些设置会降低性 ...
- gtk界面设计
一.GTK基本 #include <gtk/gtk.h> int main( int argc, char *argv[]) { GtkWidget *window; /*初始化整个GTK ...
- [Bayesian] “我是bayesian我怕谁”系列 - Naive Bayes with Prior
先明确一些潜规则: 机器学习是个collection or set of models,一切实践性强的模型都会被归纳到这个领域,没有严格的定义,’有用‘可能就是唯一的共性. 机器学习大概分为三个领域: ...
- [Arch] 01. Before Design Patterns - UML
From: 史上最全设计模式导学目录 设计模式,这是软件设计过程中的一个环节. 在这个环节之上,需要overview的事业,就是UML,一种通用的建模语言. Ref: 软件设计之UML—UML的构成[ ...
- 图表ASP:Chart
ASP:Chart 属性 System.Web.UI.DataVisualization.Charting 命名空间包含用于图表 Web 服务器控件的方法和属性. 详细了解Chart类http:// ...
- NetBpm 配置篇(2)
转载注明出处:http://www.cnblogs.com/anbylau2130/p/3877353.html 上一篇中介绍了Netbpm在IIS和CassiniWebServer服务器的安装 通过 ...
- 简单思考 如何用PHP输出本周的周三日期
简单思考 如何用PHP输出本周的周三日期?比如今天2017-10-31 计算本周周三应该是2017-11-01 自己动脑筋想一想,然后给我留言或者评论
- hadoop应用开发技术详解
<大 数据技术丛书:Hadoop应用开发技术详解>共12章.第1-2章详细地介绍了Hadoop的生态系统.关键技术以及安装和配置:第3章是 MapReduce的使用入门,让读者了解整个开发 ...
- npm yarn
1.从接触nodejs开始,一直就青睐于npm包管理工具,熟悉的命令以及提供的各种便利,也让自己没有想过更换为其他的:但是,有人也说过“海纳百川,方可走远”.因此还是有必要了解一下其他的包管理工具,比 ...
- ORACLE常用函数汇总【转】
PL/SQL单行函数和组函数详解 函数是一种有零个或多个参数并且有一个返回值的程序.在SQL中Oracle内建了一系列函数,这些函数都可被称为SQL或PL/SQL语句, 函数主要分为两大类: 单行函数 ...