【spring源码分析】IOC容器初始化——查漏补缺(四)
前言:在前几篇查漏补缺中,其实我们已经涉及到bean生命周期了,本篇内容进行详细分析。
首先看bean实例化过程:

分析:
bean实例化开始后
- 注入对象属性后(前面IOC初始化十几篇文章)。
- 检查激活Aware接口。
- 执行BeanPostProcessor前置处理
- 实例化bean,这里会检查InitializingBean和init-method方法。
- 执行BeanPostProcessor后置处理
- 注册销毁bean的回调方法(并不是必须)。
- 使用bean。
- 检查DisposableBean和destroy-method方法。
注意:Spring是不会主动去调用销毁方法,必须我们主动告知Spring容器。
示例
public class BeanLifeCycle implements BeanNameAware, BeanClassLoaderAware, BeanFactoryAware, InitializingBean, DisposableBean {
private String msg;
public BeanLifeCycle() {
System.out.println("调用构造函数:BeanLifeCycle()");
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
System.out.println("属性注入:setMsg");
this.msg = msg;
}
@Override
public void setBeanName(String name) {
System.out.println("BeanNameAware#setBeanName 被调用");
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
System.out.println("BeanClassLoaderAware#setBeanClassLoader 被调用");
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("BeanFactoryAware#setBeanFactory 被调用");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("InitializingBean#afterPropertiesSet 被调用,并对msg属性进行修改");
this.msg = "InitializingBean#afterPropertiesSet方法对msg属性进行修改";
}
@Override
public void destroy() throws Exception {
System.out.println("DisposableBean#destroy 被调用");
}
public void initMethod() {
System.out.println("init-method 被调用,并对msg属性进行修改,调用顺序在InitializingBean之后");
this.msg = "init-method方法对msg属性进行修改";
}
public void destroyMethod() {
System.out.println("destroy-method 被调用,调用顺序在DisposableBean之后");
}
}
上述为主测试类,另外为了测试BeanPostProcessor,我们还需增加如下测试类:
public class BeanLifeCycleBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("beanName=" + beanName + " 初始化之前调用:BeanPostProcessor#postProcessBeforeInitialization!!!!!");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("beanName=" + beanName + " 初始化之后调用:BeanPostProcessor#postProcessAfterInitialization!!!!!");
return bean;
}
}
具体配置如下:
<bean id="beanLifeCycle" class="com.dev.basebean.lifecycle.BeanLifeCycle"
init-method="initMethod" destroy-method="destroyMethod" p:msg="属性注入"/>
<bean id="beanLifeCycleBeanPostProcessor" class="com.dev.basebean.lifecycle.BeanLifeCycleBeanPostProcessor"/>
测试代码:
@Test
public void beanLifeCycleTest() {
ApplicationContext context = new ClassPathXmlApplicationContext("classpath*:com/dev/config/lifecycle/lifecycle.xml");
BeanLifeCycle beanLifeCycle = context.getBean(BeanLifeCycle.class);
System.out.println("msg=" + beanLifeCycle.getMsg());
((ClassPathXmlApplicationContext) context).close();
}
运行结果如下:

通过以上运行结果,我们可知Bean的生命周期,总结如下:
- Spring容器根据实例化策略对Bean进行实例化(调用其构造方法)。
- 实例化完成后,如果该bean设置了一些属性,则利用set方法进行属性设置。
- 如果该bean实现了BeanNameAware接口,则调用其setBeanName方法。
- 如果该bean实现了BeanClassLoaderAware接口,则调用其setBeanClassLoader方法。
- 如果该bean实现了BeanFactoryAware接口,则调用其setBeanFactory方法。
- 如果容器中注册了BeanPostProcessor,则会调用其postProcessBeforeInitialization方法,完成bean前置处理。
- 如果该bean实现了InitializingBean接口,则调用其afterPropertiesSet方法。
- 如果该bean配置了init-method方法,则调用其指定的方法。
- 初始化完成后,如果容器中注册了BeanPostProcessor,则会调用其postProcessAfterInitialization方法,完成bean后置处理。
- 对象初始化完成,就可以使用bean了(对其进行各种骚操作,上述示例中调用了getMsg方法)。
- 在容器关闭之前,如果该bean实现了DisposableBean接口,则调用其destroy方法。
- 在容器关闭之前,如果该bean配置了destroy-method方法,则调用其指定方法。
至此bean的生命周期结束,该bean完成了其伟大的一生。
by Shawn Chen,2019.05.05,下午。
【spring源码分析】IOC容器初始化——查漏补缺(四)的更多相关文章
- 【spring源码分析】IOC容器初始化——查漏补缺(一)
前言:在[spring源码分析]IOC容器初始化(十一)中提到了初始化bean的三个步骤: 激活Aware方法. 后置处理器应用(before/after). 激活自定义的init方法. 这里我们就来 ...
- 【spring源码分析】IOC容器初始化——查漏补缺(五)
前言:我们知道在Spring中经常使用配置文件的形式对进行属性的赋值,那配置文件的值是怎么赋值到属性上的呢,本文将对其进行分析. 首先了解一个类:PropertySourcesPlaceholderC ...
- 【spring源码分析】IOC容器初始化——查漏补缺(二)
前言:在[spring源码分析]IOC容器初始化(八)中多次提到了前置处理与后置处理,本篇文章针对此问题进行分析.Spring对前置处理或后置处理主要通过BeanPostProcessor进行实现. ...
- SPRING源码分析:IOC容器
在Spring中,最基本的IOC容器接口是BeanFactory - 这个接口为具体的IOC容器的实现作了最基本的功能规定 - 不管怎么着,作为IOC容器,这些接口你必须要满足应用程序的最基本要求: ...
- 【spring源码分析】IOC容器初始化——查漏补缺(三)
前言:本文分析InitializingBean和init-method方法,其实该知识点在AbstractAutowireCapableBeanFactory#initializeBean方法中有所提 ...
- Spring源码解析-ioc容器的设计
Spring源码解析-ioc容器的设计 1 IoC容器系列的设计:BeanFactory和ApplicatioContext 在Spring容器中,主要分为两个主要的容器系列,一个是实现BeanFac ...
- spring源码分析---IOC(1)
我们都知道spring有2个最重要的概念,IOC(控制反转)和AOP(依赖注入).今天我就分享一下spring源码的IOC. IOC的定义:直观的来说,就是由spring来负责控制对象的生命周期和对象 ...
- spring 源码之 ioc 容器的初始化和注入简图
IoC最核心就是两个过程:IoC容器初始化和IoC依赖注入,下面通过简单的图示来表述其中的关键过程:
- Spring源码阅读-IoC容器解析
目录 Spring IoC容器 ApplicationContext设计解析 BeanFactory ListableBeanFactory HierarchicalBeanFactory Messa ...
随机推荐
- Jmeter5.1——聚合报告参数分析
Jmeter5.1——聚合报告参数分析 Label: 每个JMeter的element的Name值.例如HTTP Request的Name. Samples:发出请求的数量.如果线程组中配置的是线程数 ...
- springboot启动流程(七)ioc容器refresh过程(上篇)
所有文章 https://www.cnblogs.com/lay2017/p/11478237.html 正文 在前面的几篇文章中,我们看到Environment创建.application配置文件的 ...
- JavaScript--关于闭包(closure)
js代码在执行前会做的几件事情: 1.代码检测 2.预编译:在执行代码之前会对代码中的函数以及变量提前声明 并且做一些其他的处理 1.函数在执行前的一瞬间,会生成一个OA(object action) ...
- URL - Fiddler - IIS
URL和URI URI:Uniform Resource Identifier,唯一标识一个网络资源 URL:Uniform Resource Locator,指向网络资源地址 URL是URI的子集, ...
- Linux开机启动项总结
在应急响应时有时会遇到系统被植入后门,添加启动项等操作,如果不清楚启动项的话,可能会被黑客植入一些开机启动项,无法彻底清除后门程序,所以在这梳理下启动项的东西 1.操作系统接管硬件以后,首先读入 /b ...
- http协议头
1. ctx->AddResponseHeader("Content-Type", "application/octet-stream"); ctx-&g ...
- 大数据之路week03--day05(线程 II)
今天,咱们就把线程给完完全全的结束掉,但是不是说,就已经覆盖了全部的知识点,可以说是线程的常见的问题及所含知识基本都包含. 1.多线程(理解) (1)JDK5以后的针对线程的锁定操作和释放操作 Loc ...
- rabbitmq 一些属性
消息属性 消息有14个属性,最常用的几种: deliveryMode:持久化属性 contentType:编码 replyTo:指定一个回调队列 correlationId:消息id mandator ...
- 算法:统计1-n中,1出现的次数
package edu.cqu.algorithmTest; import java.util.Scanner; /* * 给定一个十进制正整数N,写下从1开始,到N的所有整数,然后数一下其中出现的所 ...
- PhpStudy升级MySQL版本到5.7
1:备份当前数据库数据. 最好是导成 SQL 文件 2:备份 PhpStudy 下的 MySQL 文件夹.以防升级失败.还可以使用旧版本的数据库 3:下载MySQL5.7.解压.然后放在 PhpStu ...