深互动平台网站,音乐wordpress,专业软件网站建设,下载wap浏览器详解Spring Bean的生命周期
Spring Bean的生命周期包括以下阶段#xff1a;
1. 实例化Bean
对于BeanFactory容器#xff0c;当客户向容器请求一个尚未初始化的bean时#xff0c;或初始化bean的时候需要注入另一个尚未初始化的依赖时#xff0c;容器就会调用createBean进…详解Spring Bean的生命周期
Spring Bean的生命周期包括以下阶段
1. 实例化Bean
对于BeanFactory容器当客户向容器请求一个尚未初始化的bean时或初始化bean的时候需要注入另一个尚未初始化的依赖时容器就会调用createBean进行实例化。 对于ApplicationContext容器当容器启动结束后便实例化所有的bean。 容器通过获取BeanDefinition对象中的信息进行实例化。并且这一步仅仅是简单的实例化并未进行依赖注入。 实例化对象被包装在BeanWrapper对象中BeanWrapper提供了设置对象属性的接口从而避免了使用反射机制设置属性。
2. 设置对象属性依赖注入
实例化后的对象被封装在BeanWrapper对象中并且此时对象仍然是一个原生的状态并没有进行依赖注入。 紧接着Spring根据BeanDefinition中的信息进行依赖注入。 并且通过BeanWrapper提供的设置属性的接口完成依赖注入。
3. 注入Aware接口
紧接着Spring会检测该对象是否实现了xxxAware接口并将相关的xxxAware实例注入给bean。
4. BeanPostProcessor
当经过上述几个步骤后bean对象已经被正确构造但如果你想要对象被使用前再进行一些自定义的处理就可以通过BeanPostProcessor接口实现。 该接口提供了两个函数postProcessBeforeInitialzation( Object bean, String beanName ) 当前正在初始化的bean对象会被传递进来我们就可以对这个bean作任何处理。 这个函数会先于InitialzationBean执行因此称为前置处理。 所有Aware接口的注入就是在这一步完成的。postProcessAfterInitialzation( Object bean, String beanName ) 当前正在初始化的bean对象会被传递进来我们就可以对这个bean作任何处理。 这个函数会在InitialzationBean完成后执行因此称为后置处理。
5. InitializingBean与init-method
当BeanPostProcessor的前置处理完成后就会进入本阶段。 InitializingBean接口只有一个函数afterPropertiesSet()这一阶段也可以在bean正式构造完成前增加我们自定义的逻辑但它与前置处理不同由于该函数并不会把当前bean对象传进来因此在这一步没办法处理对象本身只能增加一些额外的逻辑。 若要使用它我们需要让bean实现该接口并把要增加的逻辑写在该函数中。然后Spring会在前置处理完成后检测当前bean是否实现了该接口并执行afterPropertiesSet函数。当然Spring为了降低对客户代码的侵入性给bean的配置提供了init-method属性该属性指定了在这一阶段需要执行的函数名。Spring便会在初始化阶段执行我们设置的函数。init-method本质上仍然使用了InitializingBean接口。
6. DisposableBean和destroy-method
和init-method一样通过给destroy-method指定函数就可以在bean销毁前执行指定的逻辑。
详解Spring Bean生命周期
Spring Bean的完整生命周期从创建Spring容器开始直到最终Spring容器销毁Bean这其中包含了一系列关键点。 例子演示
我们用一个简单的Spring Bean来演示一下Spring Bean的生命周期。
1.首先是一个简单的Spring Bean调用Bean自身的方法和Bean级生命周期接口方法为了方便演示它实现了BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean这4个接口同时有2个方法对应配置文件中的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;}Overridepublic String toString() {return Person [address address , name name , phone phone ];}// 这是BeanFactoryAware接口方法Overridepublic void setBeanFactory(BeanFactory arg0) throws BeansException {System.out.println(【BeanFactoryAware接口】调用BeanFactoryAware.setBeanFactory());this.beanFactory arg0;}// 这是BeanNameAware接口方法Overridepublic void setBeanName(String arg0) {System.out.println(【BeanNameAware接口】调用BeanNameAware.setBeanName());this.beanName arg0;}// 这是InitializingBean接口方法Overridepublic void afterPropertiesSet() throws Exception {System.out.println(【InitializingBean接口】调用InitializingBean.afterPropertiesSet());}// 这是DiposibleBean接口方法Overridepublic 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}Overridepublic Object postProcessAfterInitialization(Object arg0, String arg1)throws BeansException {System.out.println(BeanPostProcessor接口方法postProcessAfterInitialization对属性进行更改);return arg0;}Overridepublic 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为其提供的适配器类InstantiationAwareBeanPostProcessorAdapter来使用它如下
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 extendsInstantiationAwareBeanPostProcessorAdapter {public MyInstantiationAwareBeanPostProcessor() {super();System.out.println(这是InstantiationAwareBeanPostProcessorAdapter实现类构造器);}// 接口方法、实例化Bean之前调用Overridepublic Object postProcessBeforeInstantiation(Class beanClass,String beanName) throws BeansException {System.out.println(InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法);return null;}// 接口方法、实例化Bean之后调用Overridepublic Object postProcessAfterInitialization(Object bean, String beanName)throws BeansException {System.out.println(InstantiationAwareBeanPostProcessor调用postProcessAfterInitialization方法);return bean;}// 接口方法、设置某个属性时调用Overridepublic 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实现类构造器);}Overridepublic 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 version1.0 encodingUTF-8?beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xmlns:phttp://www.springframework.org/schema/pxmlns:aophttp://www.springframework.org/schema/aop xmlns:txhttp://www.springframework.org/schema/txxsi:schemaLocationhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsdbean idbeanPostProcessor classspringBeanTest.MyBeanPostProcessor/beanbean idinstantiationAwareBeanPostProcessor classspringBeanTest.MyInstantiationAwareBeanPostProcessor/beanbean idbeanFactoryPostProcessor classspringBeanTest.MyBeanFactoryPostProcessor/beanbean idperson classspringBeanTest.Person init-methodmyInitdestroy-methodmyDestory scopesingleton p:name张三 p:address广州p:phone15900000000 //beans6.下面测试一下
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();}
}我们来看一下结果
现在开始初始化容器
2014-5-18 15:46:20 org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext19a0c7c: 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.DefaultListableBeanFactory9934d4: 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张三, phone110]
现在开始关闭容器
【DiposibleBean接口】调用DiposibleBean.destory()
【destroy-method】调用bean的destroy-method属性指定的初始化方法Spring Bean生命周期流程图