【spring源码分析】IOC容器初始化——查漏补缺(四)
2024-10-01 04:43:27
前言:在前几篇查漏补缺中,其实我们已经涉及到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,下午。
最新文章
- GridView导出Excel(中文乱码)
- WCF中自定义消息编码器:压缩编码器的使用
- PHP 单引号和双引号的区别
- QoS 测量 (目标,方法,协议)
- jq倒计时
- PAIP: Paradigms of Artificial Intelligence Programming
- (中等) CF 585D Lizard Era: Beginning,中途相遇。
- 找到你在网页中缓存起来的flash文件
- 80C51 K1控制D1发光
- 部分手机浏览器存在将ajax请求当成广告过滤的情况,及解决方案
- oracle数据库实例启动与关闭
- Forward团队-爬虫豆瓣top250项目-开发文档
- lsof 查看文件被哪个进程占用
- Git服务器,仓库的hook监控
- Ubuntu 16.04.3 LTS 部署 Cloud Torrent
- 基于鸢尾花数据的PCA降维处理
- HDU 1269 迷宫城堡(判断有向图强连通分量的个数,tarjan算法)
- luogu【模板】三维偏序(陌上花开)
- css之水平垂直居中方式
- Linux共享对象之编译参数fPIC(转)