记一下Spring容器管理的bean的生命周期,各类方法的调用顺序。
shunxu.xml
<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd" >
<context:annotation-config></context:annotation-config>
<bean class="com.cyh.MyBeanPostProcessor"></bean>
<bean id="shunxu" class="com.cyh.Shunxu" init-method="init" destroy-method="destroy">
<property name="name" value="kyle"></property>
</bean>
</beans>
Shunxu.java
package com.cyh;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
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.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class Shunxu implements InitializingBean,BeanNameAware,BeanFactoryAware,ApplicationContextAware{
public String name;
public void setName(String name) {
this.name = name;
}
public Shunxu() {
super();
// TODO Auto-generated constructor stub
System.out.println("调用构造函数"+"--------------"+this.name);
}
@Override
public void afterPropertiesSet() throws Exception {
// TODO Auto-generated method stub
System.out.println("调用InitializingBean接口的afterPropertiesSet方法"+"--------------"+this.name);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
// TODO Auto-generated method stub
System.out.println("调用BeanFactoryAware接口的setBeanFactory方法"+"--------------"+this.name);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
// TODO Auto-generated method stub
System.out.println("调用ApplicationContextAware接口的setApplicationContext方法"+"--------------"+this.name);
}
@Override
public void setBeanName(String name) {
// TODO Auto-generated method stub
System.out.println("调用BeanNameAware接口的setBeanName方法"+"--------------"+this.name);
}
public void init(){
System.out.println("调用xml中配置的init-method"+"--------------"+this.name);
}
public void destroy(){
System.out.println("调用xml中配置的destroy-method");
}
public void sayName(){
System.out.println("业务代码"+"--------------"+this.name);
}
@PostConstruct
public void init2(){
System.out.println("调用@PostConstruct注解的方法"+"--------------"+this.name);
}
@PreDestroy
public void des(){
System.out.println("调用@PreDestroy注解的方法");
}
}
MyBeanPostProcessor.java
package com.cyh;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import com.cyh.Shunxu;
public class MyBeanPostProcessor implements BeanPostProcessor {
//注意:BeanPostProcessor会对所有的Bean进行拦截
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// TODO Auto-generated method stub
Shunxu s = (Shunxu) bean;
s.setName("andy1");
System.out.println("自定义BeanPostProcessor的postProcessBeforeInitialization执行"+"--------------"+s.name);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// TODO Auto-generated method stub
Shunxu s = (Shunxu) bean;
s.setName("andy2");
System.out.println("自定义BeanPostProcessor的postProcessAfterInitialization执行"+"--------------"+s.name);
return bean;
}
}
单元测试调用结果
调用构造函数--------------null
调用BeanNameAware接口的setBeanName方法--------------kyle
调用BeanFactoryAware接口的setBeanFactory方法--------------kyle
调用ApplicationContextAware接口的setApplicationContext方法--------------kyle
自定义BeanPostProcessor的postProcessBeforeInitialization执行--------------andy1
调用@PostConstruct注解的方法--------------andy1
调用InitializingBean接口的afterPropertiesSet方法--------------andy1
调用xml中配置的init-method--------------andy1
自定义BeanPostProcessor的postProcessAfterInitialization执行--------------andy2
业务代码--------------andy2
调用@PreDestroy注解的方法
调用xml中配置的destroy-method
结果表明顺序如下1、先调用构造函数。2、然后注入值。可以看到name成员变量被注入了值kyle。3、如果该bean实现了Aware接口,则调用接口中的方法。4、如果该bean容器注册了一个BeanPostProcessor,则调用该BeanPostProcessor的postProcessBeforeInitialization方法。5、如果该bean有@PostConstruct注解的方法,则调用该方法。6、如果该bean实现了InitializingBean接口,则调用afterPropertiesSet方法。7、调用xml中配置的init-method。8、如果该bean容器注册了一个BeanPostProcessor,则调用该BeanPostProcessor的postProcessAfterInitialization方法。此时bean已经完全准备好,可以使用9、bean容器销毁,如果bean有@PreDestroy注解的方法,则调用该方法。10、调用xml中配置的destroy-method
注意9和10只有在bean的scope为Singleton的情况下才会调用