浅谈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]调用<bean>的init-method属性指定的初始化方法"); } public void mydestory() { system.out.println("[destroy-method]调用<bean>的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]调用<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属性指定的销毁方法
总结流程:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: PHP模拟http请求的方法详解
下一篇: php使用pear_smtp发送邮件