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接口实现注入容器,再将容器后处理器InstantiationAwareBeanPostProcessorBeanPostProcessor注入容器,又在自定义Person实现了Bean级后处理器BeanNameAwareBeanFactoryAwareInitializingBeanDiposableBean接口的相关方法,最后就是在自定义的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生命周期管理的更多相关文章

  1. 【Spring Framework】Spring IOC详解及Bean生命周期详细过程

    Spring IOC 首先,在此之前,我们就必须先知道什么是ioc,ioc叫做控制反转,也可以称为依赖注入(DI),实际上依赖注入是ioc的另一种说法, 1.谁控制谁?: 在以前,对象的创建和销毁都是 ...

  2. 从启动日志看Spring IOC的初始化和Bean生命周期

    一.Tomcat中启动IoC容器的日志 启动Tomcat等容器时,控制台每次都打印出一些日志. 最近刚好在研究Spring源码,所以换个角度,从启动日志来简单的看看Spring的初始化过程! 以下是T ...

  3. spring bean生命周期管理--转

    Life Cycle Management of a Spring Bean 原文地址:http://javabeat.net/life-cycle-management-of-a-spring-be ...

  4. Spring-IOC bean 生命周期之 Lifecycle 钩子

    Lifecycle callbacks Initialization callbacks.Destruction callbacks 要与容器的bean生命周期管理交互,即容器在启动后和容器在销毁前对 ...

  5. beanFactory 设计模式 Bean 生命周期的胡言乱语,哈哈

    写在前面的话 适用读者:有一定经验的,本文不适合初学者,因为可能不能理解我在说什么 文章思路:不会一开始就像别的博客文章那样,Bean 的生命周期,源码解读(给你贴一大堆的源码).个人觉得应该由问题驱 ...

  6. beanFactory 设计模式 Bean 生命周期

    写在前面的话 适用读者:有一定经验的,本文不适合初学者,因为可能不能理解我在说什么 文章思路:不会一开始就像别的博客文章那样,Bean 的生命周期,源码解读(给你贴一大堆的源码).个人觉得应该由问题驱 ...

  7. Elasticsearch 快照生命周期管理 (SLM) 实战指南

    文章转载自:https://mp.weixin.qq.com/s/PSfgPJc4dKN2pOZd0Y02wA 1.Elasticsearch 保证高可用性的方式 Elasticsearch 保证集群 ...

  8. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(6):Spring IOC容器学习(概念、作用、Bean生命周期)

    一.IOC控制反转概念 控制反转(IOC)是一种通过描述(在Java中可以是XML或者是注解)并通过第三方去生产或获取特定对象的方式. 主动创建模式,责任在于开发者,而在被动模式下,责任归于Ioc容器 ...

  9. spring(二、bean生命周期、用到的设计模式、常用注解)

    spring(二.bean生命周期.用到的设计模式.常用注解) Spring作为当前Java最流行.最强大的轻量级框架,受到了程序员的热烈欢迎.准确的了解Spring Bean的生命周期是非常必要的. ...

随机推荐

  1. 源码分析六(org.springframework.util包之Assert类)

    一:抽象类Assert 抽象类不能够实例化对象,但是可以被继承,Assert类是功能类,所以方法都是static修饰 所以可以直接  类名.方法 调用. public abstract class A ...

  2. mysql中如何删除表上的索引?删除索引?

    需求描述: 今天在做SQL的优化的时候,想要把mysql中某个表上的索引删除掉,突然忘记语法了,找到帮助,在此记录下 操作过程: 1.查看表上的索引 show index from ti_o_sms; ...

  3. SpringMVC -- 梗概--源码--壹--数据传递

    附:实体类 Class : User package com.c61.entity; import java.text.SimpleDateFormat; import java.util.Date; ...

  4. VIM_manual

    VIM命令---Vi IMproved, a programmers text editor文本编辑 vim不同模式切换 输入模式 末行模式 光标移动 复制-粘贴-删除 可视模式 末行模式下的操作 v ...

  5. hydra 及相关示例

    http://www.cnblogs.com/mchina/archive/2013/01/01/2840815.html https://www.thc.org/thc-hydra/ 语法 # hy ...

  6. 关于OSG+QT+VS版本的问题

    CMake3.10.0 Qt5.11.0安装包只有VS2017_64版本,没有VS2017的32位版本,有VS2015的32位版本 Qt5.11.0+osg3.4在CMake的时候,会出现 CMake ...

  7. C语言中的正负数及其输出

    在数学中,数字有正负之分.在C语言中也是一样,short.int.long 都可以带上正负号,例如: //负数 ; short a2 = -0x2dc9; //十六进制 //正数 ; ; //八进制 ...

  8. HTML5和CSS3扁平化风格博客(基础篇)

    多学一点总是好的~ 自始至终都觉得的css和html效果比较美观,于是在看慕课网教程时,自己也跟着敲了深爱着的前端代码 这部分分为两部分:①基础篇:http://www.imooc.com/learn ...

  9. javaBean的理解总结

    javaBean简单理解:javaBean在MVC设计模型中是model,又称模型层,在一般的程序中,我们称它为数据层,就是用来设置数据的属性和一些行为,然后我会提供获取属性和设置属性的get/set ...

  10. 利用NtQuerySystemInformation函数遍历进程,遍历线程,获取线程挂起或运行状态

    版权声明:专注于计算机网络安全学习 https://blog.csdn.net/u011672712/article/details/51586030 1 2 3 4 5 6 7 8 9 10 11 ...