困惑!! Bean的生命周期方法链

时间:2011-11-05 13:12:36

标签: spring

public class Life implements BeanNameAware, BeanFactoryAware,  
    ApplicationContextAware, BeanPostProcessor, InitializingBean,  
    DisposableBean {  
private int counter; // counter  

public int getCounter() {  
    return counter;  
}  

public void setCounter(int counter) {  
    this.counter = counter;  
    System.out.println("1. Spring setter DI:" + this.counter);  
}  

public Life() {  
    System.out.println("0. Spring calls constructor");  
}  

@Override  
public void destroy() throws Exception {  
    System.out.println("8. DisposableBean#destroy:" + ++counter);  
}  

public void _destroy() throws Exception {  
    System.out.println("8'. bean#_destroy:" + ++counter);  
}  

@Override  
public void afterPropertiesSet() throws Exception {  
    System.out.println(new Date().getTime());  
    System.out.println("6. InitializingBean#afterPropertiesSet:"  
            + ++counter);  
}  

public void init() throws Exception {  
    System.out.println("6'. bean#init:" + ++counter);  
}  

@Override  
public Object postProcessBeforeInitialization(Object bean, String beanName)  
        throws BeansException {  
    System.out.println(new Date().getTime());  
    System.out  
            .println("5. BeanPostProcessor#postProcessBeforeInitialization:"  
                    + ++counter);  
    return bean;  
}  

@Override  
public Object postProcessAfterInitialization(Object bean, String beanName)  
        throws BeansException {  
    System.out  
            .println("7. BeanPostProcessor#postProcessAfterInitialization:"  
                    + ++counter);  
    return bean;  
}  

@Override  
public void setApplicationContext(ApplicationContext applicationContext)  
        throws BeansException {  
    System.out.println("4. ApplicationContextAware#setApplicationContext:"  
            + ++counter);  
}  

@Override  
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {  
    System.out.println("3. BeanFactoryAware#setBeanFactory:" + ++counter);  
}  

@Override  
public void setBeanName(String name) {  
    System.out.println("2. BeanNameAware#setBeanName:" + ++counter);  
}  
}

代码:

public class Test {  
    public static void main(String[] args) {  
        ApplicationContext context = new ClassPathXmlApplicationContext("life.xml");  
        context.getBean("holder");  
    }  
}

代码:

<beans xmlns="http://www.springframework.org/schema/beans"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    xsi:schemaLocation="http://www.springframework.org/schema/beans  
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">  
    <bean id="life" class="test.Life" init-method="init"  
        destroy-method="_destroy">  
        <property name="counter" value="1" />  
    </bean>  
    <bean id="holder" class="java.lang.String" />  

为什么输出是:

0. Spring calls constructor
1. Spring setter DI:1
2. BeanNameAware#setBeanName:2
3. BeanFactoryAware#setBeanFactory:3
4. ApplicationContextAware#setApplicationContext:4
**1320491454906
6. InitializingBean#afterPropertiesSet:5
6'. bean#init:6**
1320491454921
5. BeanPostProcessor#postProcessBeforeInitialization: 7
7. BeanPostProcessor#postProcessAfterInitialization:8

根据Spring in Action 3rd and Spring-Reference:

  
    

6如果任何bean实现了BeanPostProcessor接口,则Spring调用     他们的postProcessBeforeInitialization()方法。

         

7如果任何bean实现InitializingBean接口,则Spring调用它们     afterPropertiesSet()方法。同样,如果bean声明了     init-method,然后将调用指定的初始化方法。

  

订单似乎有问题?!

1 个答案:

答案 0 :(得分:1)

BeanPostProcessorpostProcess...Initialization)的方法在其他bean的初始化期间被调用,而不是在后处理器本身。类似地,在你的Spring in Action引用中postProcessBeforeInitialization()在第6点调用的方法是在上下文中声明的其他BeanPostProcessor的方法,而不是被初始化的bean的方法。

在您的情况下,在holder初始化期间会调用这些方法。

因此,BeanPostProcessor是一种允许特殊目的bean(后处理器)拦截其他bean初始化的机制。