一步步剖析spring bean生命周期
关于spring bean的生命周期,是深入学习spring的基础,也是难点,本篇文章将采用代码+图文结论的方式来阐述spring bean的生命周期,
本篇文章将阐述清楚下图。

一 项目结构及源码
1.程序目录结构

2.applicationContext.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean class="com.demo.dao.UserDao" id="userDao" scope="singleton" init-method="myInit" destroy-method="myDestroy">
<property name="userName" value="Alan_beijing"/>
</bean> <bean class="com.demo.dao.MyBeanPostProcessor" id="myBeanPostProcessor"/> </beans>
3.UserDao.java
package com.demo.dao; import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.apache.log4j.Logger; public class UserDao implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean,
DisposableBean{ private String userName;
private int count = 0; public String getUserName() {
return userName;
} //2.属性注入,注入属性为userName
public void setUserName(String userName) {
count++;
System.out.println(count + ":注入属性userName="+userName);
this.userName = userName;
} //1.无参构造函数,实例化时调用该构造函数
public UserDao() {
count++;
System.out.println(count + ":调用构造函数UserDao()");
} //3.实现BeanNameAware,获取bean id
public void setBeanName(String s) {
count++;
System.out.println(count + ":调用setBeanName()获取bean id,bean id=" + s);
} //4.实现BeanFactoryAware,获取bean工厂
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
count++;
System.out.println(count + ":调用setBeanFactory()获取bean工厂,beanFactory=" + beanFactory);
} //5.实现ApplicationContextAware,获取bean上下文
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
count++;
System.out.println(count + ":调用setApplicationContext()获取bean上下文,applicationContext=" + applicationContext);
} //6.实现InitializingBean,获取afterPropertiesSet
public void afterPropertiesSet() throws Exception {
count++;
System.out.println(count + ":调用afterPropertiesSet()");
} //7.自定义初始化方法myInit()
public void myInit() {
count++;
System.out.println(count + ":调用自定义myInit()");
} //8.实现DisposableBean,获取destroy()
public void destroy() throws Exception {
count++;
System.out.println(count + ":destroy()");
} //9.自定义销毁方法myDestroy()
public void myDestroy() {
count++;
System.out.println(count + ":调用自定义destroy()");
}
}
4.MyBeanPostProcessor.java
package com.demo.dao; import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor; public class MyBeanPostProcessor implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("=====调用postProcessBeforeInitialization()=====");
return bean;
} public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("=====调用postProcessAfterInitialization()=====");
return bean;
}
}
二 测试代码及测试结果
1.test.java
package com.demo.test; import com.demo.dao.UserDao;
import org.junit.Test;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class MyTest { @Test
public void test() {
//定义容器并初始化
//ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
AbstractApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
applicationContext.getBean(UserDao.class);
//只有关闭容器时,才会调用destroy方法
applicationContext.registerShutdownHook();
}
}
2.测试结果

三 分析
通过如上测试结果,bean生命周期流程大致如下:

1.装配bean
bean装配为bean生命周期第一环节。所谓装配bean,指将java对象转换为bean的过程。在该示例中,UserDao.jave和MyBeanPostProcessor通过xml方式转化为bean。
注意:spring框架支持四种方式装配bean:xml方式,java代码方式,自动装配和混合装配方式

2.加载applicationContext.xml并实例化
加载并实例化bean为bean生命周期的第二环节。本文示例通过ClassPathXmlApplicationContext()来加载并,当bean为singleton时,该过程就实例化对象,而不需要等待
调用applicationContext.getBean()获取bean时才实例化对象,这与prototype是不一样的。

3.属性注入
bean属性注入为bean生命周期第三环节,采用反射方式注入bean.

4.实现BeanNameAware,获取bean id
该过程为bean生命周期的第四环节,实现该接口,可以获取bean的id

5.实现BeanFactoryAware,获取bean 工厂
该过程为bean生命周期第五环节,通过实现BeanFactoryAware获取bean工厂

6.实现ApplicationContextAware,获取运用上下文
该过程为bean生命周期第六环节,通过实现ApplicationContextAware接口,获取bean上下文

7.调用Bean后置处理器,before
该过程为bean生命周期第七环节,通过实现后置处理器BeanPostProcessor获取before和after,该过程是通过AOP方式实现的,在before和after之间,发生如下8,9过程。

8.实现InitializingBean的afterPropertiesSet(),获取初始化方法
该过程为bean生命周期第八环节,通过实现InitializingBean,获取afterPropertiesSet()

9.调用自定义初始化方法,init-method
该过程为bean生命周期第九环节,实现自定义初始化方法

10.调用Bean后置处理器after
该过程为bean生命周期第十环节,后置处理器最后环节

11.关闭容器AbstractApplicationContext.registerShutDownHook()
该环节为bean生命周期第十一环节,关闭容器

12.调用DisposableBean的destroy()
该过程为bean生命周期第十二环节,实现DisposableBean接口,调用destroy()

13.调用定制化销毁方法destroy-method
该过程为bean生命周期最后环节,调用自定义销毁方法destroy-method

三 版权区
- 转载博客,必须注明博客出处
- 博主网址:http://www.cnblogs.com/wangjiming/
- 如您有新想法,欢迎提出,邮箱:2098469527@qq.com
- 专业.NET之家技术QQ群:490539956
- 专业化Java之家QQ群:924412846
- 有问必答QQ群:2098469527
- 一对一技术辅导QQ:2098469527
一步步剖析spring bean生命周期的更多相关文章
- spring bean 生命周期和 ? 作用域? spirng bean 相互依赖? jvm oom ? jvm 监控工具? ThreadLocal 原理
1. spring bean 生命周期 1. 实例化一个bean ,即new 2. 初始化bean 的属性 3. 如果实现接口 BeanNameAware ,调用 setBeanName 4. Bea ...
- Spring点滴四:Spring Bean生命周期
Spring Bean 生命周期示意图: 了解Spring的生命周期非常重要,我们可以利用Spring机制来定制Bean的实例化过程. -------------------------------- ...
- Spring Bean 生命周期之destroy——终极信仰
上一篇文章 Spring Bean 生命周期之我从哪里来 说明了我是谁? 和 我从哪里来? 的两大哲学问题,今天我们要讨论一下终极哲学我要到哪里去? 初始化 Spring Bean 有三种方式: @P ...
- 常见问题:Web/Servlet生命周期与Spring Bean生命周期
Servlet生命周期 init()初始化阶段 Servlet容器加载Servlet(web.xml中有load-on-startup=1;Servlet容器启动后用户首次向Servlet发请求;Se ...
- 大厂高频面试题Spring Bean生命周期最详解
Spring作为当前Java最流行.最强大的轻量级框架.Spring Bean的生命周期也是面试高频题,了解Spring Bean周期也能更好地帮助我们解决日常开发中的问题.程序员应该都知道Sprin ...
- Spring Bean生命周期,好像人的一生。。
大家好,我是老三,上节我们手撸了一个简单的IOC容器五分钟,手撸一个Spring容器!,这节我们来看一看Spring中Bean的生命周期,我发现,和人的一生真的很像. 简单说说IoC和Bean IoC ...
- 睡前聊一聊"spring bean 生命周期"
spring bean 生命周期=实属初销+2个常见接口+3个Aware型接口+2个生命周期接口 实属初销:spring bean生命周期只有四个阶段,即实例化->属性赋值->初始化-&g ...
- Spring Bean 生命周期2
在spring中,从BeanFactory或ApplicationContext取得的实例为Singleton,也就是预设为每一个Bean的别名只能维持一个实例,而不是每次都产生一个新的对象使用Sin ...
- Spring bean 生命周期验证
一.从源码注释看bean生命周期 从JDK源码上看,BeanFactory实现类需要支持Bean的完整生命周期,完整的初始化方法及其标准顺序(格式:接口 方法)为: 1.BeanNameAware s ...
随机推荐
- 题解 洛谷P1196 【[NOI2002]银河英雄传说】
题意 有一个划分成n列的星际战场,各列编号为1,2.....n.有n艘战舰,也依次编号1,2.....n,其中第i号战舰位于第i列. 有m条指令,每条指令格式如下 M i j 表示让第i号战舰所在列的 ...
- webstorm 突然不能用了?解决办法~
首先 感谢http://idea.lanyus.com 提供的试用方法,就在刚刚,webstorm突然就不能使了,http://idea.lanyus.com立马给出了解决办法,就是在hosts文 ...
- SpringBoot集成Zipkin实现分布式全链路监控
目录 Zipkin 简介 Springboot 集成 Zipkin 安装启动 zipkin 版本说明 项目结构 工程端口分配 引入 Maven 依赖 配置文件.收集器的设置 编写 Controller ...
- java中父类子类静态代码块、构造代码块执行顺序
父类静态(代码块,变量赋值二者按顺序执行) 子类静态 父类构造代码块 父类构造方法 子类构造代码块 子类构造方法 普通方法在实列调用的时候执行,肯定位于上面之后了 //父类A public class ...
- idea中applicationContext-trans.xml中的Cannot resolve bean 'dataSource'...的问题解决
问题如下: (applicationContext-trans.xml中的部分截图) 先了解问题是怎么出现的: 此处的dataSource是在applicationContext-dao.xml中配置 ...
- Protostuff序列化问题
最近在开发中遇到一个Protostuff序列化问题,在这记录一下问题的根源:分析一下Protostuff序列化和反序列化原理:以及怎么样避免改bug. 1. 问题描述 有一个push业务用到了mq,m ...
- MySQL 8.0主从(Master-Slave)配置
版权声明:转载请注明出处,谢谢配合. https://blog.csdn.net/zyhlwzy/article/details/80569422 MySQL 主从复制的方式有多种,本文主要演示基于基 ...
- POA理论:不要被你的目标欺骗了你
 最近通过<跃 ...
- 如何使用WordPress搭建个人博客
目录 如何使用WordPress搭建个人博客 一.在安装Linux服务器管理工具WDCP面板 二.在WDCP面板创建一个站点 二.上传博客程序到服务器 @(如何使用WordPress搭建个人博客) 如 ...
- 在IIS上启用WordPress子域名模式多站点功能
昨天负责网站的支持人员向我反馈在我们负责托管网站的WordPress在启动多站点功能后,浏览新站点或访问新站点的"Dashboard"时,都会反馈“404”错误.我检查了WordP ...