Spring Bean的生命周期详细介绍
spring作为当前java最流行、最强大的轻量级框架,受到了程序员的热烈欢迎。准确的了解spring bean的生命周期是非常必要的。我们通常使用applicationcontext作为spring容器。这里,我们讲的也是 applicationcontext中bean的生命周期。而实际上beanfactory也是差不多的,只不过处理器需要手动注册。
一、生命周期流程图:
spring bean的完整生命周期从创建spring容器开始,直到最终spring容器销毁bean,这其中包含了一系列关键点。
若容器注册了以上各种接口,程序那么将会按照以上的流程进行。下面将仔细讲解各接口作用。
二、各种接口方法分类
bean的完整生命周期经历了各种方法调用,这些方法可以划分为以下几类:
1、bean自身的方法 : 这个包括了bean本身调用的方法和通过配置文件中<bean>的init-method和destroy-method指定的方法
2、bean级生命周期接口方法 : 这个包括了beannameaware、beanfactoryaware、initializingbean和diposablebean这些接口的方法
3、容器级生命周期接口方法 : 这个包括了instantiationawarebeanpostprocessor 和 beanpostprocessor 这两个接口实现,一般称它们的实现类为“后处理器”。
4、工厂后处理器接口方法 : 这个包括了aspectjweavingenabler, configurationclasspostprocessor, customautowireconfigurer等等非常有用的工厂后处理器 接口的方法。工厂后处理器也是容器级的。在应用上下文装配配置文件之后立即调用。
三、演示
我们用一个简单的spring bean来演示一下spring bean的生命周期。
1、首先是一个简单的spring bean,调用bean自身的方法和bean级生命周期接口方法,为了方便演示,它实现了beannameaware、beanfactoryaware、initializingbean和diposablebean这4个接口,同时有2个方法,对应配置文件中<bean>的init-method和destroy-method。如下:
package springbeantest; 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; /** * @author qsk */ public class person implements beanfactoryaware, beannameaware, initializingbean, disposablebean { private string name; private string address; private int phone; private beanfactory beanfactory; private string beanname; public person() { system.out.println("【构造器】调用person的构造器实例化"); } public string getname() { return name; } public void setname(string name) { system.out.println("【注入属性】注入属性name"); this.name = name; } public string getaddress() { return address; } public void setaddress(string address) { system.out.println("【注入属性】注入属性address"); this.address = address; } public int getphone() { return phone; } public void setphone(int phone) { system.out.println("【注入属性】注入属性phone"); this.phone = phone; } @override public string tostring() { return "person [address=" + address + ", name=" + name + ", phone=" + phone + "]"; } // 这是beanfactoryaware接口方法 @override public void setbeanfactory(beanfactory arg0) throws beansexception { system.out .println("【beanfactoryaware接口】调用beanfactoryaware.setbeanfactory()"); this.beanfactory = arg0; } // 这是beannameaware接口方法 @override public void setbeanname(string arg0) { system.out.println("【beannameaware接口】调用beannameaware.setbeanname()"); this.beanname = arg0; } // 这是initializingbean接口方法 @override public void afterpropertiesset() throws exception { system.out .println("【initializingbean接口】调用initializingbean.afterpropertiesset()"); } // 这是diposiblebean接口方法 @override public void destroy() throws exception { system.out.println("【diposiblebean接口】调用diposiblebean.destory()"); } // 通过<bean>的init-method属性指定的初始化方法 public void myinit() { system.out.println("【init-method】调用<bean>的init-method属性指定的初始化方法"); } // 通过<bean>的destroy-method属性指定的初始化方法 public void mydestory() { system.out.println("【destroy-method】调用<bean>的destroy-method属性指定的初始化方法"); } }
2、接下来是演示beanpostprocessor接口的方法,如下:
package springbeantest; import org.springframework.beans.beansexception; import org.springframework.beans.factory.config.beanpostprocessor; public class mybeanpostprocessor implements beanpostprocessor { public mybeanpostprocessor() { super(); system.out.println("这是beanpostprocessor实现类构造器!!"); // todo auto-generated constructor stub } @override public object postprocessafterinitialization(object arg0, string arg1) throws beansexception { system.out .println("beanpostprocessor接口方法postprocessafterinitialization对属性进行更改!"); return arg0; } @override public object postprocessbeforeinitialization(object arg0, string arg1) throws beansexception { system.out .println("beanpostprocessor接口方法postprocessbeforeinitialization对属性进行更改!"); return arg0; } }
如上,beanpostprocessor接口包括2个方法postprocessafterinitialization和postprocessbeforeinitialization,这两个方法的第一个参数都是要处理的bean对象,第二个参数都是bean的name。返回值也都是要处理的bean对象。这里要注意。
3、instantiationawarebeanpostprocessor 接口本质是beanpostprocessor的子接口,一般我们继承spring为其提供的适配器类instantiationawarebeanpostprocessor adapter来使用它,如下:
package springbeantest; import java.beans.propertydescriptor; import org.springframework.beans.beansexception; import org.springframework.beans.propertyvalues; import org.springframework.beans.factory.config.instantiationawarebeanpostprocessoradapter; 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方法"); return null; } // 接口方法、实例化bean之后调用 @override public object postprocessafterinitialization(object bean, string beanname) throws beansexception { system.out .println("instantiationawarebeanpostprocessor调用postprocessafterinitialization方法"); return bean; } // 接口方法、设置某个属性时调用 @override public propertyvalues postprocesspropertyvalues(propertyvalues pvs, propertydescriptor[] pds, object bean, string beanname) throws beansexception { system.out .println("instantiationawarebeanpostprocessor调用postprocesspropertyvalues方法"); return pvs; } }
这个有3个方法,其中第二个方法postprocessafterinitialization就是重写了beanpostprocessor的方法。第三个方法postprocesspropertyvalues用来操作属性,返回值也应该是propertyvalues对象。
4、演示工厂后处理器接口方法,如下:
package springbeantest; 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; public class mybeanfactorypostprocessor implements beanfactorypostprocessor { public mybeanfactorypostprocessor() { super(); system.out.println("这是beanfactorypostprocessor实现类构造器!!"); } @override public void postprocessbeanfactory(configurablelistablebeanfactory arg0) throws beansexception { system.out .println("beanfactorypostprocessor调用postprocessbeanfactory方法"); beandefinition bd = arg0.getbeandefinition("person"); bd.getpropertyvalues().addpropertyvalue("phone", "110"); } }
5、配置文件如下beans.xml,很简单,使用applicationcontext,处理器不用手动注册:
<?xml version="1.0" encoding="utf-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemalocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"> <bean id="beanpostprocessor" class="springbeantest.mybeanpostprocessor"> </bean> <bean id="instantiationawarebeanpostprocessor" class="springbeantest.myinstantiationawarebeanpostprocessor"> </bean> <bean id="beanfactorypostprocessor" class="springbeantest.mybeanfactorypostprocessor"> </bean> <bean id="person" class="springbeantest.person" init-method="myinit" destroy-method="mydestory" scope="singleton" p:name="张三" p:address="广州" p:phone="15900000000" /> </beans>
6、下面测试一下:
package springbeantest; import org.springframework.context.applicationcontext; import org.springframework.context.support.classpathxmlapplicationcontext; public class beanlifecycle { public static void main(string[] args) { system.out.println("现在开始初始化容器"); applicationcontext factory = new classpathxmlapplicationcontext("springbeantest/beans.xml"); system.out.println("容器初始化成功"); //得到preson,并使用 person person = factory.getbean("person",person.class); system.out.println(person); system.out.println("现在开始关闭容器!"); ((classpathxmlapplicationcontext)factory).registershutdownhook(); } }
关闭容器使用的是实际是abstractapplicationcontext的钩子方法。
我们来看一下结果:
现在开始初始化容器 2014-5-18 15:46:20 org.springframework.context.support.abstractapplicationcontext preparerefresh 信息: refreshing org.springframework.context.support.classpathxmlapplicationcontext@19a0c7c: startup date [sun may 18 15:46:20 cst 2014]; root of context hierarchy 2014-5-18 15:46:20 org.springframework.beans.factory.xml.xmlbeandefinitionreader loadbeandefinitions 信息: loading xml bean definitions from class path resource [springbeantest/beans.xml] 这是beanfactorypostprocessor实现类构造器!! beanfactorypostprocessor调用postprocessbeanfactory方法 这是beanpostprocessor实现类构造器!! 这是instantiationawarebeanpostprocessoradapter实现类构造器!! 2014-5-18 15:46:20 org.springframework.beans.factory.support.defaultlistablebeanfactory preinstantiatesingletons 信息: pre-instantiating singletons in org.springframework.beans.factory.support.defaultlistablebeanfactory@9934d4: defining beans [beanpostprocessor,instantiationawarebeanpostprocessor,beanfactorypostprocessor,person]; root of factory hierarchy instantiationawarebeanpostprocessor调用postprocessbeforeinstantiation方法 【构造器】调用person的构造器实例化 instantiationawarebeanpostprocessor调用postprocesspropertyvalues方法 【注入属性】注入属性address 【注入属性】注入属性name 【注入属性】注入属性phone 【beannameaware接口】调用beannameaware.setbeanname() 【beanfactoryaware接口】调用beanfactoryaware.setbeanfactory() beanpostprocessor接口方法postprocessbeforeinitialization对属性进行更改! 【initializingbean接口】调用initializingbean.afterpropertiesset() 【init-method】调用<bean>的init-method属性指定的初始化方法 beanpostprocessor接口方法postprocessafterinitialization对属性进行更改! instantiationawarebeanpostprocessor调用postprocessafterinitialization方法 容器初始化成功 person [address=广州, name=张三, phone=110] 现在开始关闭容器! 【diposiblebean接口】调用diposiblebean.destory() 【destroy-method】调用<bean>的destroy-method属性指定的初始化方法
以上就是对java spring bean 生命周期的资料整理,后续继续补充相关资料,谢谢大家对本站的支持!