springBean的生命周期描述了交由spring管理的bean从创建,属性赋值,代理扩展,销毁的过程。在不同的阶段spring都提供了相应的接口提供扩展。
Spring生命周期
各个接口与方法调用时机
先声明一下,问中讲到实例化代表着调用类的构造方法,讲到初始化代表着bean指定的init-method。
BeanPostProcessor接口
接口BeanPostProcessor有两个方法postProcessBeforeInitialization,postProcessAfterInitialization,分别在类初始化前后进行调用,对原有的类进行一些加强或封装。
@Override
public Object postProcessBeforeInitialization(Object arg0, String arg1)
throws BeansException {
// 类初始化之前调用
return arg0;
}
@Override
public Object postProcessAfterInitialization(Object arg0, String arg1)
throws BeansException {
// 类初始化之后调用
return arg0;
}
InstantiationAwareBeanPostProcessor接口
InstantiaionAwareBeanPostProcessor接口也是BeanPostProcessor的子接口,提供了一些扩展的方法,postProcessBeforeInstantiation,postProcessAfterInstantiation分别在bean实例化前后调用。postProcessPropertyValues 在给某个类设置属性前调用,可以覆盖将要设置的属性值。
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
// 实例化Bean之后调用
return super.postProcessAfterInstantiation(bean, beanName);
}
@Override
public Object postProcessBeforeInstantiation(Class beanClass,
String beanName) throws BeansException {
// 实例化Bean之前调用
return null;
}
@Override
public PropertyValues postProcessPropertyValues(PropertyValues pvs,
PropertyDescriptor[] pds, Object bean, String beanName)
throws BeansException {
// 设置属性前调用
return pvs;
}
BeanNameAware与BeanFactoryAware接口
这两个接口分别给bean中注入beanName(bean在容器中的名字),beanFactory(当前的容器)
// 这是BeanNameAware接口方法
@Override
public void setBeanName(String arg0) {
this.beanName = arg0;
}
// 这是BeanFactoryAware接口方法
@Override
public void setBeanFactory(BeanFactory arg0) throws BeansException {
this.beanFactory = arg0;
}
InitializingBean接口
InitializaingBean接口在给bean设置完属性后调用
@Override
public void afterPropertiesSet() throws Exception {
// InitializingBean 接口方法,在bean属性设置完成后调用
}
DiposibleBean接口
在bean销毁时调用
@Override
public void destroy() throws Exception {
}
代码示例
spirng版本 5.0.8.RELEASE
BeanFactoryPostProcessor
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");
}
}
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对bean进行更改!");
return arg0;
}
@Override
public Object postProcessBeforeInitialization(Object arg0, String arg1)
throws BeansException {
System.out
.println("--->【BeanPostProcessor接口方法】postProcessBeforeInitialization对bean进行更改!");
return arg0;
}
}
InstantiationAwareBeanPostProcessor,一般都使用它的适配器类,重写对应的方法,InstantiationAwareBeanPostProcessor也是一个BeanPostProcessor
public class MyInstantiationAwareBeanPostProcessor extends
InstantiationAwareBeanPostProcessorAdapter {
public MyInstantiationAwareBeanPostProcessor() {
super();
System.out
.println("【InstantiationAwareBeanPostProcessorAdapter实现类构造器!!】");
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
System.out.println("--->【InstantiationAwareBeanPostProcessor调用】postProcessAfterInstantiation方法");
return super.postProcessAfterInstantiation(bean, beanName);
}
// 接口方法、实例化Bean之前调用
@Override
public Object postProcessBeforeInstantiation(Class beanClass,
String beanName) throws BeansException {
System.out.println("--->【InstantiationAwareBeanPostProcessor调用】postProcessBeforeInstantiation方法");
return null;
}
// 接口方法、设置某个属性时调用
@Override
public PropertyValues postProcessPropertyValues(PropertyValues pvs,
PropertyDescriptor[] pds, Object bean, String beanName)
throws BeansException {
pvs.getPropertyValue("name").setConvertedValue("替换");
System.out
.println("【InstantiationAwareBeanPostProcessor调用】postProcessPropertyValues方法");
return pvs;
}
}
自定义bean
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("【bean构造器】调用Person的构造器实例化");
}
public String getName() {
return name;
}
public void setName(String name) {
System.out.println("【bean注入属性】注入属性name");
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
System.out.println("【bean注入属性】注入属性address");
this.address = address;
}
public int getPhone() {
return phone;
}
public void setPhone(int phone) {
System.out.println("【bean注入属性】注入属性phone");
this.phone = phone;
}
@Override
public String toString() {
return "Person [address=" + address + ", name=" + name + ", phone="
+ phone + ", beanName="+beanName +"]";
}
// 这是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属性指定的初始化方法");
}
}
spring配置文件
<?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="com.tttiger.MyBeanPostProcessor">
</bean>
<bean id="instantiationAwareBeanPostProcessor" class="com.tttiger.MyInstantiationAwareBeanPostProcessor">
</bean>
<bean id="beanFactoryPostProcessor" class="com.tttiger.MyBeanFactoryPostProcessor">
</bean>
<bean id="person" class="com.tttiger.Person" init-method="myInit"
destroy-method="myDestory" scope="singleton" p:name="张三" p:address="广州"
p:phone="1590000" />
</beans>
启动类
public static void main(String[] args) {
System.out.println("《现在开始初始化容器》");
ApplicationContext factory = new ClassPathXmlApplicationContext("classpath:application.xml");
System.out.println("《容器初始化成功》");
//得到Preson,并使用
Person person = factory.getBean("person",Person.class);
System.out.println(person);
System.out.println("《现在开始关闭容器》");
((ClassPathXmlApplicationContext)factory).registerShutdownHook();
}
console out
《现在开始初始化容器》
【BeanFactoryPostProcessor实现类构造器!!】
【BeanFactoryPostProcessor调用】postProcessBeanFactory方法
【BeanPostProcessor实现类构造器!!】
【InstantiationAwareBeanPostProcessorAdapter实现类构造器!!】
--->【InstantiationAwareBeanPostProcessor调用】postProcessBeforeInstantiation方法
【bean构造器】调用Person的构造器实例化
--->【InstantiationAwareBeanPostProcessor调用】postProcessAfterInstantiation方法
【InstantiationAwareBeanPostProcessor调用】postProcessPropertyValues方法
【bean注入属性】注入属性address
【bean注入属性】注入属性name
【bean注入属性】注入属性phone
【BeanNameAware接口】调用BeanNameAware.setBeanName()
【BeanFactoryAware接口】调用BeanFactoryAware.setBeanFactory()
--->【BeanPostProcessor接口方法】postProcessBeforeInitialization对bean进行更改!
【InitializingBean接口】调用InitializingBean.afterPropertiesSet()
【init-method】调用<bean>的init-method属性指定的初始化方法
--->【BeanPostProcessor接口方法】postProcessAfterInitialization对bean进行更改!
《容器初始化成功》
Person [address=广州, name=替换, phone=110, beanName=person]
《现在开始关闭容器》
【DiposibleBean接口】调用DiposibleBean.destory()
【destroy-method】调用<bean>的destroy-method属性指定的初始化方法