BeanFactory中bean生命周期
- 如果容器注册了InstantiationAwareBeanPostProcessor接口,则在实例化bean之前,将调用接口的postProcessBeforeInstantiation()方法。
- 根据配置情况调用bean构造函数或工厂方法实例化Bean.
- 如果容器注册了InstantiationAwareBeanPostProcessor接口,则在实例化bean之后,将调用接口的postProcessAfterInstantiation()方法。
- 如果bean设置了属性信息,那么容器在这一步着手将配置值设置到Bean对应的属性中,不过在设置属性之前先调用InstantiationAwareBeanPostProcessor接口的postProcessPropertyValues方法。
- 调用bean的属性设置方法设置属性。
- 如果bean实现了BeanNameAware接口,那么将调用setBeanName()方法。
- 如果实现了BeanFactoryAware接口,则调用setBeanFactory()方法。
- 如果BeanFactory装配了BeanPostProcessor后处理器,则将调用BeanPostProcessor的postProcessBeforeInitialization方法。
- 如果Bean实现了InitializingBean,则调用afterPropertiesSet()方法。
- 如果在bean中通过init-method属性定义了初始化方法,则将执行这个方法。
- 调用BeanPostProcessor的postProcessAfterInitialization方法。
- 如果bean的scope为prototype,那么将bean的引用返回给调用者。调用者负责bean后续声明的管理,spring不再管理这个bean的声明周期。如果是singleton,那么bean放入spring ioc容器的缓冲池中。并将bean返回给调用者。
- 对于singleton bean,当容器关闭时,如果bean实现了DisposableBean接口,将调用此接口的destory()方法。
- 对于singleton bean,如果定义了destory-method属性,那么将调用这个方法。
方法分类
Bean的完整生命周期经历了各种方法调用,这些方法可以划分为以下几类:
Bean自身的方法 : 这个包括了Bean本身调用的方法和通过配置文件中的init-method和destroy-method指定的方法
Bean级生命周期接口方法 : 这个包括了BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean这些接口的方法
容器级生命周期接口方法 : 这个包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 这两个接口实现,一般称它们的实现类为“后处理器”。
工厂后处理器接口方法 : 这个包括了AspectJWeavingEnabler, ConfigurationClassPostProcessor, CustomAutowireConfigurer等等非常有用的工厂后处理器 接口的方法。工厂后处理器也是容器级的。在应用上下文装配配置文件之后立即调用。
InstantiationAwareBeanPostProcessor其实为BeanPostProcessor的子接口,spring提供了一个适配器类BeanPostProcessorAdapter。一般继承这个类。
示例
public class Car implements BeanFactoryAware,BeanNameAware,InitializingBean,
DisposableBean{
private String brand;
public Car() {
System.out.println("调用car构造函数");
}
public void setBrand(String brand) {
System.out.println("调用setBrand()方法设置属性");
this.brand = brand;
}
public void myinit(){
System.out.println("init-methd invoke");
}
public void mydestroy(){
System.out.println("destroy-methd invoke");
}
@Override
public void destroy() throws Exception {
System.out.println("disposableBean.destroy()");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("afterPropertiesSet");
}
@Override
public void setBeanName(String name) {
System.out.println("setBeanName");
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("setBeanFactory");
}
}
public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter{
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if("car".equals(beanName)){
System.out.println("InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation");
}
return null;
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if("car".equals(beanName)){
System.out.println("InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation");
}
return true;
}
@Override
public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean,
String beanName) throws BeansException {
if("car".equals(beanName)){
System.out.println("InstantiationAwareBeanPostProcessor.postProcessPropertyValues");
}
return pvs;
}
}
public class MyBeanPostProcessor implements BeanPostProcessor{
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if("car".equals(beanName)){
System.out.println("BeanPostProcessor.postProcessBeforeInitialization");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if("car".equals(beanName)){
System.out.println("BeanPostProcessor.postProcessAfterInitialization");
}
return bean;
}
}
public class BeanLifeCycleTest {
public static void main(String[] args) throws IOException {
Resource resource = new ClassPathResource("applicationContext.xml");
System.out.println(resource.getURL());
BeanFactory beanFactory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader =
new XmlBeanDefinitionReader((DefaultListableBeanFactory)beanFactory);
reader.loadBeanDefinitions(resource);
((ConfigurableBeanFactory)beanFactory).addBeanPostProcessor(new MyBeanPostProcessor());
((ConfigurableBeanFactory)beanFactory).addBeanPostProcessor(new MyInstantiationAwareBeanPostProcessor());
Car car = (Car) beanFactory.getBean("car");
((DefaultListableBeanFactory)beanFactory).destroySingletons();
}
}
spring配置文件:
<bean id="car" class="com.topview.springBean.model.Car" init-method="myinit"
destroy-method="mydestroy">
<property name="brand" value="大众"></property>
</bean>
运行结果如下:
InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation
调用car构造函数
InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation
InstantiationAwareBeanPostProcessor.postProcessPropertyValues
调用setBrand()方法设置属性
setBeanName
setBeanFactory
BeanPostProcessor.postProcessBeforeInitialization
afterPropertiesSet
init-methd invoke
BeanPostProcessor.postProcessAfterInitialization
disposableBean.destroy()
destroy-methd invoke
注:后处理器的实际调用顺序和注册顺序时无关 的。在具有多个后处理器的情况下,必须通过实现Ordered接口来确定调用顺序。
spring还拥有一个bean后置处理器InitDestroyAnnotationBeanPostProcessor,负责对标注了@PostConstruct,@PreDestroy的bean进行处理。(如果在applicationContext中,则已经默认装配了该处理器)
ApplicationContext中bean的生命周期
- 与Factory中的相似,不同的是如果bean实现了ApplicationContext接口,则会调用setApplicationContext方法。
- 如果配置文件中声明了工厂后处理器接口BeanFactoryPostProcessor的实现类,则应用上下文在装载配置文件之后,初始化bean实例之前将调用这些BeanFactoryPostProcessor对配置信息进行加工处理。工厂后处理器是容器级的,仅在应用上下文初始化时调用一次。
- ApplicationContext与BeanFactory最大的不同在于,前者会利用java反射机制自动识别出配置文件中定义的后处理器,并自动将他们注册到应用上下文中。而后者需要通过代码手动注册。在ApplicationContext中,只需在配置文件中通过bean标签定义工厂后处理器和bean后处理器,它们就会按预期的方式进行。