浅谈Spring bean 生命周期验证

本篇文章主要介绍了浅谈Spring bean 生命周期验证,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

一、从源码注释看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接口。

package spring.ioc; import org.springframework.beans.BeansException; import org.springframework.beans.factory.beanfactory; import org.springframework.beans.factory.beanfactoryAware; import org.springframework.beans.factory.BeanNameAware; import org.springframework.beans.factory.disposableBean; import org.springframework.beans.factory.InitializingBean; public class Person implements beanfactoryAware, BeanNameAware, InitializingBean, disposableBean { private String name; private String mobile; public Person() { super(); System.out.println("[构造器] 调用Person的构造器实例化"); } public String getName() { return name; } public void setName(String name) { System.out.println("[属性注入] name="+name); this.name = name; } public String getMobile() { return mobile; } public void setMobile(String mobile) { System.out.println("[属性注入] mobile="+mobile); this.mobile = mobile; } @Override public void destroy() throws Exception { System.out.println("[接口disposableBean.destroy() ]"); } @Override public void afterPropertiesSet() throws Exception { System.out.println("[接口InitializingBean.afterPropertiesSet() ]"); } @Override public void setBeanName(String name) { System.out.println("[接口BeanNameAware.setBeanName() ]"); } @Override public void setbeanfactory(beanfactory beanfactory) throws BeansException { System.out.println("[接口beanfactoryAware.setbeanfactory() ]"); } public void myInit(){ System.out.println("[init-method]调用的init-method属性指定的初始化方法"); } public void myDestory() { System.out.println("[destroy-method]调用的destroy-method属性指定的销毁方法"); } }

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

package spring.ioc; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanDeFinition; import org.springframework.beans.factory.config.beanfactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListablebeanfactory; /** * * @ClassName:MybeanfactoryPostProcessor * @Description:自定义工厂后处理器 * @author diandian.zhang * @date 2017年10月25日下午7:14:09 */ public class MybeanfactoryPostProcessor implements beanfactoryPostProcessor { public MybeanfactoryPostProcessor() { super(); System.out.println("[MybeanfactoryPostProcessor工厂后处理器]beanfactoryPostProcessor实现类构造器!!"); } @Override public void postProcessbeanfactory(ConfigurableListablebeanfactory arg0) throws BeansException { System.out.println("[MybeanfactoryPostProcessor工厂后处理器]beanfactoryPostProcessor.postProcessbeanfactory()获取bean定义后添加属性mobile=110"); BeanDeFinition bd = arg0.getBeanDeFinition("person"); bd.getPropertyValues().addPropertyValue("mobile", "110"); } }

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

package spring.ioc; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; /** * * @ClassName:MyBeanPostProcessor * @Description:自定义Bean后处理器 * @author diandian.zhang * @date 2017年10月25日下午7:03:53 */ public class MyBeanPostProcessor implements BeanPostProcessor { public MyBeanPostProcessor() { super(); System.out.println("这是BeanPostProcessor实现类构造器!!"); } /** * * @Description 初始化前,处理器 * @param bean * @param beanName * @return * @throws BeansException * @author diandian.zhang * @date 2017年10月25日下午7:07:02 * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization(java.lang.Object, java.lang.String) */ @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("BeanPostProcessor接口方法postProcessBeforeInitialization对属性进行更改!beanName="+beanName); return bean; } /** * * @Description 初始化后,处理器 * @param bean * @param beanName * @return * @throws BeansException * @author diandian.zhang * @date 2017年10月25日下午7:07:07 * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization(java.lang.Object, java.lang.String) */ @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("BeanPostProcessor接口方法postProcessAfterInitialization对属性进行更改!beanName="+beanName); return bean;//注意,如果返回null,后续BeanPostProcessor不会再执行 } }

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

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

package spring.ioc; import java.beans.PropertyDescriptor; import org.springframework.beans.BeansException; import org.springframework.beans.PropertyValues; import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter; /** * * @ClassName:MyInstantiationAwareBeanPostProcessor * @Description:BeanPostProcessor的子类,增加了更多自定方法 * @author diandian.zhang * @date 2017年10月25日下午7:09:15 */ public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter { public MyInstantiationAwareBeanPostProcessor() { super(); System.out.println("这是InstantiationAwareBeanPostProcessorAdapter实现类构造器!!"); } // 接口方法、实例化Bean之前调用 @Override public Object postProcessBeforeInstantiation(Class> beanClass,String beanName) throws BeansException { System.out.println("InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法[实例化Bean之前调用 ]beanname="+beanName); return null; } // 接口方法、实例化Bean之后调用 @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out .println("InstantiationAwareBeanPostProcessor调用postProcessAfterInitialization方法[实例化Bean之后调用]beanname="+beanName); return bean; } // 接口方法、设置某个属性调用 @Override public PropertyValues postProcesspropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { System.out.println("InstantiationAwareBeanPostProcessor调用postProcesspropertyValues方法 pvs="+pvs+",beanName="+beanName); return pvs; } }

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

package spring.ioc; import org.junit.Test; 6 import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClasspathXmlApplicationContext;10 import spring.aop.xml.dao.Dao; /** * * @ClassName:IOCTest * @Description:测试类 * @author diandian.zhang * @date 2017年10月25日下午4:42:01 */ public class IOCTest { @Test public void iocPersontest(){ System.out.println("=============容器初始化======start========="); @SuppressWarnings("resource") ApplicationContext applicationContext = new ClasspathXmlApplicationContext("simple_spring_bean.xml");//源码入口 System.out.println("=============容器初始化=======end========"); System.out.println("=============获取person bean====start======="); Person person = applicationContext.getBean("person",Person.class);//获取Bean System.out.println("=============获取person bean====end=======,person类名="+person.getClass().getName()); System.out.println("=============注册关闭钩子,关闭容器(JVM shutdown)时触发钩子!================"); ((ClasspathXmlApplicationContext)applicationContext).registerShutdownHook(); } }

直接运行,结果如下:

=============容器初始化======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]调用的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]调用的destroy-method属性指定的销毁方法

总结流程:

相关文章

HashMap是Java中最常用的集合类框架,也是Java语言中非常典型...
在EffectiveJava中的第 36条中建议 用 EnumSet 替代位字段,...
介绍 注解是JDK1.5版本开始引入的一个特性,用于对代码进行说...
介绍 LinkedList同时实现了List接口和Deque接口,也就是说它...
介绍 TreeSet和TreeMap在Java里有着相同的实现,前者仅仅是对...
HashMap为什么线程不安全 put的不安全 由于多线程对HashMap进...