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. 使用apache的poi实现导入导出excel

    1.jar包:poi-3.14-20160307.jar.poi-ooxml-3.14-20160307.jar 2.导入(本例实现了解析excel生成List): @Override public ...

  2. QT 运行崩溃:The inferior stopped because it received a signal from the Operating System

    最近在研究QT自带的boxes例子,自己派生一个图形项,但是在运行生成该图形项时程序直接退出了~ Qt Creater调试代码,问题定位如下代码行: 执行1270行时弹出错误消息框: 于是上网查找资料 ...

  3. centos图形界面的开启和关闭

    一般来说centos主要用于服务器端,所以很少开启图形化界面,但是有时候为了工作方便也会偶尔开启图形界面,下面就让简单谈谈如何开启图形化界面, 当然简化安装是没有这个程序的需要自行安装,可以yum安装 ...

  4. C# toolstrip 上添加DateTimePicker Control控件

    private void AddDTPtoToolstrip( n){DateTimePicker dtp = DateTimePicker;dtp.Width = 110;dtp.Format = ...

  5. Tomcat------启动出错

    描述:在cmd中,执行startup.bar时,报错:Using CLASSPATH: "E:\Tomcat\bin\bootstrap.jar;E:\Tomcat\bin\tomcat-j ...

  6. ios开发之--UIViewContentMode详解

    在开发当中有时会有这样的需求,将从服务器端下载下来的图片添加到imageView 当中展示,但是下载下来的图片尺寸大小不固定,宽高也有可能不成比例 如果直接设置imageView的image属性而不设 ...

  7. 【代码审计】UKCMS_v1.1.0 文件上传漏洞分析

      0x00 环境准备 ukcms官网:https://www.ukcms.com/ 程序源码下载:http://down.ukcms.com/down.php?v=1.1.0 测试网站首页: 0x0 ...

  8. solr java demo 基础入门

      <!--solr的maven依赖--> <dependencies> <dependency> <groupId>org.apache.solr&l ...

  9. 关于GDI+的一些使用基础设置

    一.新建一个MFC的单文档工程,例如工程名字叫GDIPLUSTEST1. 二.在工程的stdafx.h头文件中添加入 #include "gdiplus.h" using name ...

  10. FileReader类和FileWriter类的基本用法示例

    package com.example.io; import java.io.File; import java.io.FileReader; import java.io.FileWriter; i ...