只会一点java

java持续学习者,每月一篇博客。罗列出技术栈,慢慢完善,持续学习,总有一天,你会追上甚至超越曾经的大神。
  博客园  :: 首页  :: 联系 :: 订阅 订阅  :: 管理

Spring bean 生命周期验证

Posted on 2017-10-25 20:44  只会一点java  阅读(1358)  评论(0编辑  收藏  举报

一、从源码注释看bean生命周期

从JDK源码注释上看,BeanFactory实现类需要支持Bean的完整生命周期,完整的初始化方法及其标准顺序(格式:接口 方法)为:

1.BeanNameAware setBeanName 设置bean名称
2.BeanClassLoaderAware setBeanClassLoader 设置bean类加载器
3.BeanFactoryAware setBeanFactory 设置bean工厂
4.EnvironmentAware setEnvironment 设置环境:profiles+properties
5.EmbeddedValueResolverAware setEmbeddedValueResolver 设置嵌入式值解析器
6.ResourceLoaderAware setResourceLoader 设置资源载入器,只适用于在应用程序上下文中运行
7.ApplicationEventPublisherAware setApplicationEventPublisher注入应用事件发布器ApplicationEventPublisher
8.MessageSourceAware setMessageSource 设置国际化支持
9.ApplicationContextAware setApplicationContext 设置应用上下文
10.ServletContextAware setServletContext 设置servlet上下文
11.BeanPostProcessors postProcessBeforeInitialization 执行bean处理器前置方法
12.InitializingBean afterPropertiesSet 执行初始化Bean设置完属性后置方法
13.a custom init-method definition 执行自定义初始化方法
14.BeanPostProcessors postProcessAfterInitialization 执行bean处理器后置方法

销毁顺序:
1.DestructionAwareBeanPostProcessors postProcessBeforeDestruction 销毁处理器的前置方法
2.DisposableBean destroy Bean销毁回调方法
3.a custom destroy-method definition 用户自定义销毁方法

 

当然这里面不是所有方法都走一遍,核心方法流程图如下图:

 

二、测试验证

2.1分析原理

前面说的17个步骤都可以测试,我们选取其中的8个步骤进行测试如下:

初始化流程

1.BeanNameAware setBeanName 设置bean名称
3.BeanFactoryAware setBeanFactory 设置bean工厂
11.BeanPostProcessors postProcessBeforeInitialization 执行bean处理器前置方法
12.InitializingBean afterPropertiesSet 执行初始化Bean设置完属性后置方法
13.a custom init-method definition 执行自定义初始化方法
14.BeanPostProcessors postProcessAfterInitialization 执行bean处理器后置方法

销毁流程

2.DisposableBean destroy Bean销毁回调方法
3.a custom destroy-method definition 用户自定义销毁方法

 2.2 代码清单

 1.构建一个Person类,实现BeanFactoryAware, BeanNameAware, InitializingBean, DisposableBean接口。

 1 package spring.ioc;
 2 
 3 import org.springframework.beans.BeansException;
 4 import org.springframework.beans.factory.BeanFactory;
 5 import org.springframework.beans.factory.BeanFactoryAware;
 6 import org.springframework.beans.factory.BeanNameAware;
 7 import org.springframework.beans.factory.DisposableBean;
 8 import org.springframework.beans.factory.InitializingBean;
 9 
10 public class Person implements BeanFactoryAware, BeanNameAware, InitializingBean, DisposableBean {
11     
12     private String name;
13     
14     private String mobile;
15      
16     public Person() {
17         super();
18         System.out.println("[构造器] 调用Person的构造器实例化");
19     }
20 
21     public String getName() {
22         return name;
23     }
24 
25     public void setName(String name) {
26         System.out.println("[属性注入] name="+name);
27         this.name = name;
28     }
29 
30     public String getMobile() {
31         return mobile;
32     }
33 
34     public void setMobile(String mobile) {
35         System.out.println("[属性注入] mobile="+mobile);
36         this.mobile = mobile;
37     }
38 
39     @Override
40     public void destroy() throws Exception {
41         System.out.println("[接口DisposableBean.destroy() ]");
42     }
43 
44     @Override
45     public void afterPropertiesSet() throws Exception {
46         System.out.println("[接口InitializingBean.afterPropertiesSet() ]");
47     }
48 
49     @Override
50     public void setBeanName(String name) {
51         System.out.println("[接口BeanNameAware.setBeanName() ]");
52     }
53 
54     @Override
55     public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
56         System.out.println("[接口BeanFactoryAware.setBeanFactory() ]");
57     }
58 
59     public void myInit(){
60         System.out.println("[init-method]调用<bean>的init-method属性指定的初始化方法");
61     }
62     
63     public void myDestory() {
64         System.out.println("[destroy-method]调用<bean>的destroy-method属性指定的销毁方法");
65     }
66 
67 }

2.自定义工厂后处理器,复写postProcessBeanFactory方法,获取bean定义后添加属性mobile=110

 1 package spring.ioc;
 2 
 3 import org.springframework.beans.BeansException;
 4 import org.springframework.beans.factory.config.BeanDefinition;
 5 import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
 6 import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
 7 
 8 /**
 9  * 
10  * @ClassName:MyBeanFactoryPostProcessor
11  * @Description:自定义工厂后处理器
12  * @author diandian.zhang
13  * @date 2017年10月25日下午7:14:09
14  */
15 public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
16 
17     public MyBeanFactoryPostProcessor() {
18         super();
19         System.out.println("[MyBeanFactoryPostProcessor工厂后处理器]BeanFactoryPostProcessor实现类构造器!!");
20     }
21 
22     @Override
23     public void postProcessBeanFactory(ConfigurableListableBeanFactory arg0)
24             throws BeansException {
25         System.out.println("[MyBeanFactoryPostProcessor工厂后处理器]BeanFactoryPostProcessor.postProcessBeanFactory()获取bean定义后添加属性mobile=110");
26         BeanDefinition bd = arg0.getBeanDefinition("person");
27         bd.getPropertyValues().addPropertyValue("mobile", "110");
28     }
29 
30 }

3.自定义Bean后处理器,复写postProcessBeforeInitialization和postProcessAfterInitialization2个方法,分别对应初始化前后时的操作。

 1 package spring.ioc;
 2 
 3 import org.springframework.beans.BeansException;
 4 import org.springframework.beans.factory.config.BeanPostProcessor;
 5 
 6 /**
 7  * 
 8  * @ClassName:MyBeanPostProcessor
 9  * @Description:自定义Bean后处理器
10  * @author diandian.zhang
11  * @date 2017年10月25日下午7:03:53
12  */
13 public class MyBeanPostProcessor implements BeanPostProcessor {
14 
15     public MyBeanPostProcessor() {
16         super();
17         System.out.println("这是BeanPostProcessor实现类构造器!!");
18     }
19 
20     /**
21      * 
22      * @Description 初始化前,处理器
23      * @param bean
24      * @param beanName
25      * @return
26      * @throws BeansException
27      * @author diandian.zhang
28      * @date 2017年10月25日下午7:07:02
29      * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization(java.lang.Object, java.lang.String)
30      */
31     @Override
32     public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
33         System.out.println("BeanPostProcessor接口方法postProcessBeforeInitialization对属性进行更改!beanName="+beanName);
34         return bean;
35     }
36     
37     /**
38      * 
39      * @Description 初始化后,处理器
40      * @param bean
41      * @param beanName
42      * @return
43      * @throws BeansException
44      * @author diandian.zhang
45      * @date 2017年10月25日下午7:07:07
46      * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization(java.lang.Object, java.lang.String)
47      */
48     @Override
49     public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
50         System.out.println("BeanPostProcessor接口方法postProcessAfterInitialization对属性进行更改!beanName="+beanName);
51         return bean;//注意,如果返回null,后续BeanPostProcessor不会再执行
52     }
53 
54     
55 }

4.自定义实例化bean后处理器适配器,复写postProcessBeforeInstantiation、postProcessBeforeInstantiation、postProcessPropertyValues分别对应实例化Bean前调用、实例化Bean后调用、设置某个属性时调用

注意:InstantiationAwareBeanPostProcessorAdapter ,这里是实例化Instantiation,不是初始化Initialization!!!

 1 package spring.ioc;
 2 
 3 import java.beans.PropertyDescriptor;
 4 
 5 import org.springframework.beans.BeansException;
 6 import org.springframework.beans.PropertyValues;
 7 import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
 8 
 9 /**
10  * 
11  * @ClassName:MyInstantiationAwareBeanPostProcessor
12  * @Description:BeanPostProcessor的子类,增加了更多自定方法
13  * @author diandian.zhang
14  * @date 2017年10月25日下午7:09:15
15  */
16 public class MyInstantiationAwareBeanPostProcessor extends
17         InstantiationAwareBeanPostProcessorAdapter {
18 
19     public MyInstantiationAwareBeanPostProcessor() {
20         super();
21         System.out.println("这是InstantiationAwareBeanPostProcessorAdapter实现类构造器!!");
22     }
23 
24     // 接口方法、实例化Bean之前调用
25     @Override
26     public Object postProcessBeforeInstantiation(Class<?> beanClass,String beanName) throws BeansException {
27         System.out.println("InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法[实例化Bean之前调用 ]beanname="+beanName);
28         return null;
29     }
30 
31     // 接口方法、实例化Bean之后调用
32     @Override
33     public Object postProcessAfterInitialization(Object bean, String beanName)
34             throws BeansException {
35         System.out .println("InstantiationAwareBeanPostProcessor调用postProcessAfterInitialization方法[实例化Bean之后调用]beanname="+beanName);
36         return bean;
37     }
38 
39     // 接口方法、设置某个属性时调用
40     @Override
41     public PropertyValues postProcessPropertyValues(PropertyValues pvs,
42             PropertyDescriptor[] pds, Object bean, String beanName)
43             throws BeansException {
44         System.out.println("InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法 pvs="+pvs+",beanName="+beanName);
45         return pvs;
46     }
47 }

5.测试类,使用ClassPathXmlApplicationContext从xml中读取bean配置文件生成applicationContext容器应用上下文,这一步对应容器初始化。第二部从应用上下文中获取bean。最后一步注册一个关闭钩子,在容器关闭时触发。

 1 package spring.ioc;
 2 
 3 import org.junit.Test; 6 import org.springframework.context.ApplicationContext;
 7 import org.springframework.context.support.ClassPathXmlApplicationContext;10 
11 import spring.aop.xml.dao.Dao;
12 
13 /**
14  * 
15  * @ClassName:IOCTest
16  * @Description:测试类
17  * @author diandian.zhang
18  * @date 2017年10月25日下午4:42:01
19  */
22 public class IOCTest {
35     
36     @Test
37     public void iocPersonTest(){
38         System.out.println("=============容器初始化======start=========");
39         @SuppressWarnings("resource")
40         ApplicationContext applicationContext = new ClassPathXmlApplicationContext("simple_spring_bean.xml");//源码入口
41         System.out.println("=============容器初始化=======end========");
42         System.out.println("=============获取person bean====start=======");
43         Person person = applicationContext.getBean("person",Person.class);//获取Bean
44         System.out.println("=============获取person bean====end=======,person类名="+person.getClass().getName());
45         System.out.println("=============注册关闭钩子,关闭容器(JVM shutdown)时触发钩子!================");
46         ((ClassPathXmlApplicationContext)applicationContext).registerShutdownHook();
47     }
48 }

直接运行,结果如下:

=============容器初始化======start=========
log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment).
log4j:WARN Please initialize the log4j system properly.
[MyBeanFactoryPostProcessor工厂后处理器]BeanFactoryPostProcessor实现类构造器!!
[MyBeanFactoryPostProcessor工厂后处理器]BeanFactoryPostProcessor.postProcessBeanFactory()获取bean定义后添加属性mobile=110
这是BeanPostProcessor实现类构造器!!
这是InstantiationAwareBeanPostProcessorAdapter实现类构造器!!
InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法[实例化Bean之前调用 ]beanname=person
[构造器] 调用Person的构造器实例化
InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法 pvs=PropertyValues: length=2; bean property 'mobile'; bean property 'name',beanName=person
[属性注入] mobile=110
[属性注入] name=张三
[接口BeanNameAware.setBeanName() ]
[接口BeanFactoryAware.setBeanFactory() ]
BeanPostProcessor接口方法postProcessBeforeInitialization对属性进行更改!beanName=person
[接口InitializingBean.afterPropertiesSet() ]
[init-method]调用<bean>的init-method属性指定的初始化方法
BeanPostProcessor接口方法postProcessAfterInitialization对属性进行更改!beanName=person
InstantiationAwareBeanPostProcessor调用postProcessAfterInitialization方法[实例化Bean之后调用]beanname=person
=============容器初始化=======end========
=============获取person bean====start=======
=============获取person bean====end=======,person类名=spring.ioc.Person
=============注册关闭钩子,关闭容器(JVM shutdown)时触发钩子!================
[接口DisposableBean.destroy() ]
[destroy-method]调用<bean>的destroy-method属性指定的销毁方法

总结流程:

 

====================================

参考

1.JDK8源码

2.全文参考Spring Bean的生命周期(非常详细),