简介

本片文章主要讲Spring IOC容器中 bean 的生命周期

Spring bean 生命周期

Spring 中bean的声明周期 可以分为如下4个阶段:

  1. 实例化阶段--Instantiation 调用构造函数
  2. 属性赋值阶段--Populate 设置依赖注入
  3. 初始化---Initialization 调用Init方法
  4. 销毁---Destruction 调用Destory方法

各阶段的接口和方法

每个阶段 都是具体的接口和方法 如果按照方法和接口的类型我们可以分为如下几类:

  1. bean 本身的接口和方法 init方法,destroy方法
  2. bean 生命周期的接口 BeanNameAware,ApplicationContextAware,BeanFactoryAware,InitializingBean,DisposableBean
  3. 容器级生命周期接口 主要有BeanPostProcessor,InstantiationAwareBeanPostProcessor
  4. 工厂级的处理接口 BeanFactoryPostProcessor

执行流程

刚才上面列举了 很多接口和方法 那执行的顺序是什么呢?

BeanLifecycle 代码如下

/**
* @ClassName BeanLifecycle
* @Auther burgxun
* @Description: Spring bean 的生命周期
* @Date 2020/4/21 12:45
**/
public class BeanLifecycle implements BeanNameAware, ApplicationContextAware, BeanFactoryAware,InitializingBean,
DisposableBean { public BeanLifecycle() {
System.out.println("========>【Bean】【BeanLifecycle】执行 构造函数");
} @Override
public void setBeanName(String s) {
System.out.println("========>【Bean】【BeanNameAware】 执行方法 setBeanName -------》实例化bean后 " +
"为bean 注入BeanName-" + s);
} @Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("========>【Bean】【ApplicationContextAware】 执行方法 " +
"setApplicationContext-------》实例化bean后 为bean注入ApplicationContext");
} @Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("========>【Bean】【BeanFactoryAware】 执行方法 setBeanFactory -------》实例化bean后 ");
} @Override
public void afterPropertiesSet() throws Exception {
System.out.println("========>【Bean】【InitializingBean】执行方法 afterPropertiesSet -------》bean" +
" 实例化完成后 初始化之前调用");
} public void beanInit() {
System.out.println("========>【Bean】【BeanLifecycle】 执行方法 Init-Method " +
"-------》xml中配置bean实例化完成后 初始化方法");
} public void beanDestroy() {
System.out.println("========>【Bean】【BeanLifecycle】 执行方法 Destroy-Method " +
"-------》xml中配置销毁bean之前 回调方法" +
" ");
} public void sayHello() {
System.out.println("========>【Bean】【BeanLifecycle】执行方法 bean中方法 -------》 sayHello");
} @Override
public void destroy() throws Exception {
System.out.println("========>【Bean】【DisposableBean】 执行方法 destroy -------》 销毁 Bean 的回调方法");
}
}

ContainerLifecycle方法如下:

**
* @ClassName ContainerLifecycle
* @Auther burgxun
* @Description: Spring 容器 生命周期
* @Date 2020/4/21 14:44
**/
@Component
public class ContainerLifecycle extends InstantiationAwareBeanPostProcessorAdapter {
public ContainerLifecycle() {
System.out.println("========>【Container】【ContainerLifecycle】 执行 构造函数");
} @Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
System.out.println("========>【Container】【InstantiationAwareBeanPostProcessor】执行 " +
"postProcessBeforeInstantiation" +
"-------》Bean实例化之前调用 beanName:" + beanName);
return null;
} @Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
System.out.println("========>【Container】【InstantiationAwareBeanPostProcessor】执行 " +
"postProcessAfterInstantiation " +
"-------》Bean实例化之后调用 beanName:" + beanName);
return super.postProcessAfterInstantiation(bean, beanName);
} @Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("========>【Container】【BeanPostProcessor】 执行" +
"postProcessBeforeInitialization " +
"-------》Bean初始化之前调用 beanName:" + beanName);
return super.postProcessBeforeInitialization(bean, beanName);
} @Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("========>【Container】【BeanPostProcessor】执行 " +
"postProcessAfterInitialization " +
"-------》Bean初始化之后调用 beanName:" + beanName);
return super.postProcessAfterInitialization(bean, beanName);
} @Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
System.out.println("========>【Container】【InstantiationAwareBeanPostProcessor】 执行 postProcessProperties " +
"Bean 属性赋值的时候 beanName:" + beanName);
return null;
}
}

FactoryLifecycle 代码如下

/**
* @ClassName FactoryLifecycle
* @Auther burgxun
* @Description: Spring beanFactory 如下
* @Date 2020/4/21 17:32
**/
public class FactoryLifecycle implements BeanFactoryPostProcessor { public FactoryLifecycle() {
System.out.println("========>【BeanFactory】【BeanFactoryPostProcessor】 执行 FactoryLifecycle " +
"构造函数");
} @Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
System.out.println("========>【BeanFactory】【BeanFactoryPostProcessor】 执行方法 " +
"postProcessBeanFactory ");
}
}

Spring bean Test

public class SpringTest {

    @Test
public void mySpringBeanTest() { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath" +
":Spring-life.xml");
BeanLifecycle beanLifecycle = (BeanLifecycle) context.getBean("beanLifecycle"); beanLifecycle.sayHello();
context.close();
}
}

执行结果是:

【BeanFactory】【BeanFactoryPostProcessor】 执行 FactoryLifecycle 构造函数
【BeanFactory】【BeanFactoryPostProcessor】 执行方法 postProcessBeanFactory
【Container】【ContainerLifecycle】 执行 构造函数
【Container】【InstantiationAwareBeanPostProcessor】执行 postProcessBeforeInstantiation-------》Bean实例化之前调用 beanName:beanLifecycle
【Bean】【BeanLifecycle】执行 构造函数
【Container】【InstantiationAwareBeanPostProcessor】执行 postProcessAfterInstantiation -------》Bean实例化之后调用 beanName:beanLifecycle
【Container】【InstantiationAwareBeanPostProcessor】 执行 postProcessProperties Bean 属性赋值的时候 beanName:beanLifecycle
【Bean】【BeanNameAware】 执行方法 setBeanName -------》实例化bean后 为bean 注入BeanName-beanLifecycle
【Bean】【BeanFactoryAware】 执行方法 setBeanFactory -------》实例化bean后 为bean注入BeanFactory
【Bean】【ApplicationContextAware】 执行方法 setApplicationContext-------》实例化bean后 为bean注入ApplicationContext
【Container】【BeanPostProcessor】 执行postProcessBeforeInitialization -------》Bean初始化之前调用 beanName:beanLifecycle
【Bean】【InitializingBean】执行方法 afterPropertiesSet -------》bean 实例化完成后 初始化之前调用
【Bean】【BeanLifecycle】 执行方法 Init-Method -------》xml中配置bean实例化完成后 初始化方法
【Container】【BeanPostProcessor】执行 postProcessAfterInitialization -------》Bean初始化之后调用 beanName:beanLifecycle
【Bean】【BeanLifecycle】执行方法 bean中方法 -------》 sayHello
【Bean】【DisposableBean】 执行方法 destroy -------》 销毁 Bean 的回调方法
【Bean】【BeanLifecycle】 执行方法 Destroy-Method -------》xml中配置销毁bean之前 回调方法

那继续画个流程图吧

graph TB
A[Bean]
B[BeanFactory构造]
C[BeanFactoryPostProcessor-postProcessBeanFactory]
D[Container构造]
E[InstantiationAwareBeanPostProcessor-postProcessBeforeInstantiation]
F[InstantiationAwareBeanPostProcessor-postProcessAfterInstantiation]
H[Bean构造]
I[InstantiationAwareBeanPostProcessor-postProcessProperties]
J[BeanNameAware-setBeanName]
K[BeanFactoryAware-setBeanFactory]
L[ApplicationContextAware-setApplicationContext]
M[BeanPostProcessor-postProcessBeforeInitialization]
N[InitializingBean-afterPropertiesSet]
X[Bean中Init-Method]
Y[BeanPostProcessor-postProcessAfterInitialization]
Z[Bean中方法]
U[DisposableBean-destroy]
V[Bean中Destroy-Method]

A-->B
Y-->Z
subgraph BeanFactory
B-->C
end

subgraph 实例化 Instantiation
C-->D
D-->E
E-->H
H-->F
end

subgraph 设置属性和相关依赖 Populate
F-->I
I-->J
J-->K
K-->L
end

subgraph 初始化 Initialization
L-->M
M-->N
N-->X
X-->Y
end

subgraph 销毁 Destruction
Z-->U
U-->V
end

好了方法的流程都整理好了

再次小结一下

Spring 中初始化和销毁bean的三种调用方法

  1. 通过InitializingBean/DisposableBean 接口来完成
  2. 通过在bean的元素配置上加 init-method/destroy-method来指定 调用的方法
  3. 通过@PostConstruct 或@PreDestroy注解来指定 调用方法

他们的执行顺序是怎样的呢?

答案是 注解》接口方法》bean元素里面配置的方法

谈谈Spring bean的生命周期(一)的更多相关文章

  1. 第37讲 谈谈Spring Bean的生命周期和作用域

    在企业应用软件开发中,Java 是毫无争议的主流语言,开放的 Java EE 规范和强大的开源框架功不可没,其中 Spring 毫无疑问已经成为企业软件开发的事实标准之一.今天这一讲,我将补充 Spr ...

  2. Spring学习手札(四)谈谈Spring Bean的生命周期及作用域

    在Spring中,那些组成应用程序的主体以及由Spring IoC容器所管理的对象,被称之为Bean.Bean与应用程序中其他对象(比如自己创建类)的区别就是,Bean是由IoC容器创建于销毁的.在S ...

  3. Spring Bean的生命周期(非常详细)

    Spring作为当前Java最流行.最强大的轻量级框架,受到了程序员的热烈欢迎.准确的了解Spring Bean的生命周期是非常必要的.我们通常使用ApplicationContext作为Spring ...

  4. spring bean的生命周期

    掌握好spring bean的生命周期,对spring的扩展大有帮助.  spring bean的生命周期(推荐看)  spring bean的生命周期

  5. Spring Bean的生命周期,《Spring 实战》书中的官方说法

    连着两天的面试 ,都问到了 Spring 的Bean的生命周期,其中还包括 昨晚一波阿里的电话面试.这里找到了Spring 实战中的官方说法.希望各位要面试的小伙伴记住,以后有可能,或者是有时间 去看 ...

  6. Spring Bean的生命周期相关博客

    最近得面试题一直 问 Spring 得生命周期,鉴于自己还未阅读过源码 所以只能是自己 背一波了.属实不懂硬背得作用,但是无奈被各位面试官打败了.等以后有时间了 一定要阅读几遍spring的 源码 有 ...

  7. Spring Bean的生命周期详解(转)

    Spring作为当前Java最流行.最强大的轻量级框架,受到了程序员的热烈欢迎.准确的了解Spring Bean的生命周期是非常必要的.我们通常使用ApplicationContext作为Spring ...

  8. Spring动态代理及Spring Bean的生命周期

    数组添加值 public class DiTest { /** * 数组 */ private String [] arrays; /** * List:集合 */ private List<I ...

  9. Spring(三)--Spring bean的生命周期

    Spring bean的生命周期 ApplicationContext Bean生命周期流程 1.需要的实体类 ackage com.xdf.bean; import org.springframew ...

随机推荐

  1. webWMS开发过程记录(三)- 需求分析(略)

    行业:汽车零部件制造 大方向:非唯一码,需有一套简单.易用.受控的误操作撤回机制 现状(略) 目标(略) 注:由于项目是自己根据以往经验,自己开发的,且开发时间不固定,故需求分析暂略,我会把工作重点放 ...

  2. SpringBoot实现图片上传demo&Nginx进行代理显示

    公司项目需要一个图片上传的功能,就图片能上传到服务器(公司用的windows服务器),然后nginx能进行代理访问到就行了,先简单介绍一下nginx,然后再来实现功能. 一.nginx简介 Nginx ...

  3. 通过神秘代码登录自己的QQ

    通过神秘代码登录自己的QQ 如图:是怎么做成的呢? 其实很明显,这个是QQ号码的16进制 所以网上搜索进制转换打开一个网页 输入自己的QQ号码,得到16进制的QQ号码 在QQ页面账号处先添加0x然后复 ...

  4. 五分钟!用python绘制漂亮的系统架构图

    Diagrams 是一个基于Python绘制云系统架构的模块,它能够通过非常简单的描述就能可视化架构,并支持以下6个云产品的图标: AWS.Azure.GCP.K8s.阿里云 和 Oracle 云 基 ...

  5. 详解 迭代器 —— Iterator接口、 ListIterator接口 与 并发修改异常

    (请关注 本人"Collection集合"博文--<详解 Collection集合>) Iterator接口(迭代器): 概述: 对 collection 进行迭代的迭 ...

  6. 1. ajax递归并发处理

    在某些情况下可能会需要循环ajax请求,可以利用递归发送 function recursion( index,array ) { if ( index < array.length ) { // ...

  7. Spring Boot 自定义kafka 消费者配置 ContainerFactory最佳实践

    Spring Boot 自定义kafka 消费者配置 ContainerFactory最佳实践 本篇博文主要提供一个在 SpringBoot 中自定义 kafka配置的实践,想象这样一个场景:你的系统 ...

  8. java 脚本引擎执行js

    为用到时,使用方便直接保存一下代码 package com.xzlf.reflectTest; import java.io.BufferedReader; import java.io.FileIn ...

  9. 理解java容器底层原理--手动实现HashSet

    HashSet的底层其实就是HashMap,换句话说HashSet就是简化版的HashMap. 直接上代码: package com.xzlf.collection2; import java.uti ...

  10. Centos史上新版最详细步骤-Linux无脑命令式oracle11g静默安装

    1. 关闭selinux 1.1 sed -i "s/SELINUX=enforcing/SELINUX=disabled/" /etc/selinux/config 1.2 或者 ...