Bean生命周期讲解和作用
一、 Bean运行步骤和概括
创建(实例化-初始化)-使用-销毁,而在Spring中,Bean对象周期当然遵从这一过程,但是Spring提供了许多对外接口,允许开发者对三个过程(实例化、初始化、销毁)的前后做一些操作。
二、bean接口、方法说明
1.Bean自身方法:init-method/destroy-method,通过为配置文件bean定义中添加相应属性指定相应执行方法。
2.Bean级生命周期接口:BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean这些接口的方法。每个Bean选择实现,可选择各自的个性化操作。
3.容器级生命周期接口方法:这个包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 这两个接口实现(前者继承自后者),一般称它们的实现类为“后处理器”(其实我觉得这个名称对新手有误导的意思),这些接口是每个bean实例化或初始化时候都会调用。
4.工厂后处理器接口方法:这些方法也是容器级别的,但它们是在上下文装置配置文件之后调用,例如BeanFactoryPostProcessor、 CustomAutowireConfigurer等。
三、代码实现
HelloWorld
package com.DZY.bean.test;
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 HelloWorld implements BeanNameAware, BeanFactoryAware, InitializingBean, DisposableBean {
private String message;
public HelloWorld() {
System.out.println("3.HelloWorld struct.......");
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public void xml_init() {
// xml开头的表示配置文件配置,这里是bean配置中init-method配置调用
System.out.println("11.HelloWorld 初始化(init-method)");
}
public void xml_destroy() {
// destroy-method 配置调用
System.out.println("16.HelloWorld 销毁(destroy-method)");
}
public void setBeanName(String s) {
// 属性注入后调用
System.out.println("6.setBeanName(BeanNameAware) 属性注入后调用, 此时s = " + s);
}
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
// setBeanName 后调用
System.out.println("7.setBeanFactory(BeanFactory) setBeanName后调用");
}
public void afterPropertiesSet() throws Exception {
// processBeforeInitialization(BeanPostProcessor)后调用
System.out.println("10.afterPropertiesSet(InitializingBean) processBeforeInitialization之后,配置的xml_init之前调用");
}
public void destroy() throws Exception {
System.out.println("15.destroy(DisposableBean) 在processAfterInitialization之后,配置的xml_destroy之前调用");
}
}
InitBeanPostProcessor
package com.DZY.bean.test;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
/**
* Created by fuchaochao on 16/8/12.
*/
public class InitBeanPostProcessor implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
System.out.println("8.postProcessBeforeInitialization(BeanPostProcessor), bean = " + o.getClass());
return o;
}
public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
System.out.println("12.postProcessAfterInitialization(BeanPostProcessor), bean = " + o.getClass());
return o;
}
}
InstanceBeanPostProcessor
package com.DZY.bean.test;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import java.beans.PropertyDescriptor;
import java.util.Arrays;
/**
* Created by fuchaochao on 16/8/12.
*/
public class InstanceBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
public Object postProcessBeforeInstantiation(Class<?> aClass, String s) throws BeansException {
System.out.println("2.实例化bean之前调用,即调用bean类构造函数之前调用 " + aClass.getName());
/*try {
return Class.forName(""+aClass);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}*/
return null;//其实我不是很明白这里返回值得作用,之后可能会去深入理解
}
public boolean postProcessAfterInstantiation(Object o, String s) throws BeansException {
System.out.println("4.返回boolean,bean实例化后调用,并且返回false则不会注入属性");
return true;
}
public PropertyValues postProcessPropertyValues(PropertyValues propertyValues, PropertyDescriptor[] propertyDescriptors, Object o, String s) throws BeansException {
System.out.println("5.postProcessPropertyValues,在属性注入之前调用...... beanName = " + s + " 属性名集合 : " + Arrays.toString(propertyValues.getPropertyValues()));
//System.out.println("message = " + ((HelloWorld)o).getMessage()); 这里可以看到message还是null
return propertyValues;//这里要返回propertyValues,否则属性无法注入
}
public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
System.out.println("9.postProcessBeforeInitialization(InstantiationAwareBeanPostProcessor) ");
return o;
}
public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
System.out.println("13.postProcessAfterInitialization(InstantiationAwareBeanPostProcessor) ");
return o;
}
}
BeanFactoryPostProcessorTest
package com.DZY.bean.test;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
/**
* Created by fuchaochao on 16/8/12.
*/
public class BeanFactoryPostProcessorTest implements BeanFactoryPostProcessor {
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
//configurableListableBeanFactory.getBeanDefinition("appcontext-service.xml");
System.out.println("1.postProcessBeanFactory(BeanFactoryPostProcessor) 工厂后处理器, ApplicationContext容器初始化中refresh()中调用");
}
}
SpringTest2
package com.DZY.bean.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* bean 生命周期测试
* @author Aromanic150
*
*/
public class SpringTest2 {
public static void main(String[] args){
ApplicationContext context = new ClassPathXmlApplicationContext("/spring-context.xml");
HelloWorld obj = (HelloWorld)context.getBean("helloWorld");
System.out.println("14.Bean working, message = " + obj.getMessage());
// ((ClassPathXmlApplicationContext)context).refresh();
((ClassPathXmlApplicationContext)context).close();
}
}