[Spring]Bean在IOC容器的生命周期

Spring中整个Bean的生命周期经过了各个方法的调用,如下:

  • Bean自身的方法:这个包括了Bean本身调用的方法和通过配置文件中的init-method和destroy-method指定的方法
  • Bean级生命周期接口方法:这个包括了BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean这些接口的方法。
  • 容器级生命周期接口方法:这个包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 这两个接口实现,一般称它们的实现类为“后处理器”。
  • 工厂后处理器接口方法:这个包括了AspectJWeavingEnabler, ConfigurationClassPostProcessor, CustomAutowireConfigurer等等非常有用的工厂后处理器接口的方法。工厂后处理器也是容器级的。在应用上下文装配配置文件之后立即调用。

首先介绍Bean级生命周期接口:BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean

我将这四个接口分为两类:
前两个接口负责在实例化Bean时,为Bean注入beanName(Bean在IOC容器的ID)与beanFactory属性

    /**
     * BeanFactoryAware接口,只声明了一个方法:用来获取BeanFactory
     * BeanNameAware接口,只声明了一个方法:用来获取BeanName
     */

后两个接口负责为Bean进行实例化之前初始化和销毁时销毁。

    /**
     * InitializingBean:
     * 在spring初始化bean的时候,如果该bean是实现了InitializingBean接口,
     * 并且同时在配置文件中指定了init-method,
     * 系统则是先调用InitializingBean的afterPropertiesSet方法,
     * 然后在调用init-method中指定的方法。
     * */


    /**
     * DisposableBean:
     * 在spring初始化bean的时候,如果该bean是实现了DisposableBean接口,
     * 并且同时在配置文件中指定了destroy-method,
     * 系统则是先调用DisposableBean的destroy方法,
     * 然后在调用destroy-method中指定的方法。
     */

下面介绍容器级生命周期接口:InstantiationAwareBeanPostProcessor 和 BeanPostProcessor

    /**
     * InstantiationAwareBeanPostProcessor 接口本质是
     * BeanPostProcessor的子接口,
     * 一般我们继承Spring为其提供的适配器类
     * InstantiationAwareBeanPostProcessorAdapter来使用它,
     * 
     * 此接口可以在Bean实例化前、Bean实例化后分别进行操作
     * 也可以对Bean实例化之后进行属性操作
     */
    /**
     * BeanPostProcessor接口包括2个方法
     * postProcessAfterInitialization和postProcessBeforeInitialization,
     * 这两个方法的第一个参数都是要处理的Bean对象,第二个参数都是Bean的name。
     * 返回值也都是要处理的Bean对象。
     * 
     * 此接口的方法可以对Bean的属性进行更改
     */

下面代码演示Bean的生命周期

Person - JavaBean

public class Person implements BeanFactoryAware, BeanNameAware,
        InitializingBean, DisposableBean{

    /**
     * BeanFactoryAware接口,只声明了一个方法:用来获取BeanFactory
     * BeanNameAware接口,只声明了一个方法:用来获取BeanName
     */

    /**
     * InitializingBean:
     * 在spring初始化bean的时候,如果该bean是实现了InitializingBean接口,
     * 并且同时在配置文件中指定了init-method,
     * 系统则是先调用InitializingBean的afterPropertiesSet方法,
     * 然后在调用init-method中指定的方法。
     * */

    /**
     * DisposableBean:
     * 在spring初始化bean的时候,如果该bean是实现了DisposableBean接口,
     * 并且同时在配置文件中指定了destroy-method,
     * 系统则是先调用DisposableBean的destroy方法,
     * 然后在调用destroy-method中指定的方法。
     */

    private String name;
    private BeanFactory beanFactory;
    private String beanName;

    public Person() {
        System.out.println("【构造器】调用Person的构造器实例化");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        System.out.println("【注入属性】注入属性name,---name="+name);
        this.name = name;
    }

    @Override
    public String toString() {
        return "Person [name=" + name + "]";
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("【DiposibleBean接口】调用" +
                "DiposibleBean.destory()");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("【InitializingBean接口】调用" +
                "InitializingBean.afterPropertiesSet()");
    }

    @Override
    public void setBeanName(String beanName) {
        System.out.println("【BeanNameAware接口】调用" +
                "BeanNameAware.setBeanName()---beanName="+beanName);
        this.beanName = beanName;
    }

    @Override
    public void setBeanFactory(BeanFactory arg0) throws BeansException {
        System.out.println("【BeanFactoryAware接口】调用" +
                "BeanFactoryAware.setBeanFactory()");
        this.beanFactory = arg0;
    }


    // 通过的init-method属性指定的初始化方法
    public void myInit() {
        System.out.println("【init-method】调用" +
                "的init-method属性指定的初始化方法");
    }

    // 通过的destroy-method属性指定的初始化方法
    public void myDestory() {
        System.out.println("【destroy-method】调用" +
                "的destroy-method属性指定的初始化方法");
    }

}

BeanFactoryPostProcessor接口的实现,可修改XML对Bean配置的元信息

public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor{

    /**
     * BeanFactoryPostProcessor可以对bean的定义(配置元数据)进行处理。
     * 也就是说,Spring IoC容器允许BeanFactoryPostProcessor
     * 在容器实际实例化任何其它的bean之前读取配置元数据,并有可能修改它。
     * 如果你愿意,你可以配置多个BeanFactoryPostProcessor。
     * 你还能通过设置'order'属性来控制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("person1");
        bd.getPropertyValues().addPropertyValue("name", "张三三");
    }
}

InstantiationAwareBeanPostProcessorAdapter的实现

public class MyInstantiationAwareBeanPostProcessor 
    extends InstantiationAwareBeanPostProcessorAdapter {

    /**
     * InstantiationAwareBeanPostProcessor 接口本质是
     * BeanPostProcessor的子接口,
     * 一般我们继承Spring为其提供的适配器类
     * InstantiationAwareBeanPostProcessorAdapter来使用它,
     * 
     * 此接口可以在Bean实例化前、Bean实例化后分别进行操作
     * 也可以对Bean实例化之后进行属性操作
     */

    public MyInstantiationAwareBeanPostProcessor (){
        super();
        System.out.println(
                "这是InstantiationAwareBeanPostProcessorAdapter" +
                "实现类构造器!!");
    }

    // 接口方法、实例化Bean之前调用
    @Override
    public Object postProcessBeforeInstantiation(Class beanClass,
            String beanName) throws BeansException {
        System.out.println("InstantiationAwareBeanPostProcessor" +
                "调用postProcessBeforeInstantiation方法");
        return null;
    }

    /**
     * postProcessAfterInitialization重写了BeanPostProcessor的方法。
     */
    // 接口方法、实例化Bean之后调用
    @Override
    public Object postProcessAfterInitialization(Object bean, 
            String beanName) throws BeansException {
        System.out.println("InstantiationAwareBeanPostProcessor" +
                "调用postProcessAfterInitialization方法");
        return bean;
    }

    /**
     * 第三个方法postProcessPropertyValues用来操作属性,返回值也应该是PropertyValues对象
     */
    // 接口方法、设置某个属性时调用
    @Override
    public PropertyValues postProcessPropertyValues(PropertyValues pvs,
            PropertyDescriptor[] pds, Object bean, String beanName)
            throws BeansException {
        System.out.println("InstantiationAwareBeanPostProcessor" +
                "调用postProcessPropertyValues方法");
        System.out.println("beanName="+beanName);
        return pvs;
    }
}

BeanPostProcessor的实现

public class MyBeanPostProcessor implements BeanPostProcessor {

    /**
     * BeanPostProcessor接口包括2个方法
     * postProcessAfterInitialization和postProcessBeforeInitialization,
     * 这两个方法的第一个参数都是要处理的Bean对象,第二个参数都是Bean的name。
     * 返回值也都是要处理的Bean对象。
     * 
     * 此接口的方法可以对Bean的属性进行更改
     */

    public MyBeanPostProcessor() {
        super();
        System.out.println("这是BeanPostProcessor实现类构造器!!");
    }

    @Override
    public Object postProcessAfterInitialization(Object obj, String objName)
            throws BeansException {
        Person person = (Person) obj;
        person.setName("之后--赵六");
        System.out.println("BeanPostProcessor接口方法" +
                "postProcessAfterInitialization对属性进行更改!" +
                "---"+"obj="+obj+"---objName="+objName);
        return obj;
    }

    @Override
    public Object postProcessBeforeInitialization(Object obj, String objName)
            throws BeansException {
        Person person = (Person) obj;
        person.setName("之前--李四");
        System.out.println("BeanPostProcessor接口方法" +
                "postProcessBeforeInitialization对属性进行更改!" +
                "---"+"obj="+obj+"---objName="+objName);
        return obj;
    }
}

XML配置信息

    id="beanPostProcessor" 
        class="com.bean.MyBeanPostProcessor">
    

    id="instantiationAwareBeanPostProcessor" 
        class="com.bean.MyInstantiationAwareBeanPostProcessor">
    

    id="beanFactoryPostProcessor" 
        class="com.bean.MyBeanFactoryPostProcessor">
    

    id="person1" class="com.bean.Person" init-method="myInit"
        destroy-method="myDestory" scope="singleton">
        <property name="name" value="aaa">property>
    

测试代码

    public static void main(String[] args) {
        System.out.println("现在开始初始化IOC容器");
        ApplicationContext context = 
                new ClassPathXmlApplicationContext("spring2.xml");
        System.out.println("IOC容器初始化成功");    
        Person person = (Person) context.getBean("person1");
        System.out.println("使用person对象的toString:"+person);
        System.out.println("现在开始关闭容器!");
        ((ClassPathXmlApplicationContext)context).registerShutdownHook();
    }

运行结果

现在开始初始化IOC容器
这是BeanFactoryPostProcessor实现类构造器!!
BeanFactoryPostProcessor调用postProcessBeanFactory方法
这是BeanPostProcessor实现类构造器!!
这是InstantiationAwareBeanPostProcessorAdapter实现类构造器!!
InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法
【构造器】调用Person的构造器实例化
InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法
beanName=person1
【注入属性】注入属性name,---name=张三三
【BeanNameAware接口】调用BeanNameAware.setBeanName()---beanName=person1
【BeanFactoryAware接口】调用BeanFactoryAware.setBeanFactory()
【注入属性】注入属性name,---name=之前--李四
BeanPostProcessor接口方法postProcessBeforeInitialization对属性进行更改!---obj=Person [name=之前--李四]---objName=person1
【InitializingBean接口】调用InitializingBean.afterPropertiesSet()
【init-method】调用<bean>的init-method属性指定的初始化方法
【注入属性】注入属性name,---name=之后--赵六
BeanPostProcessor接口方法postProcessAfterInitialization对属性进行更改!---obj=Person [name=之后--赵六]---objName=person1
InstantiationAwareBeanPostProcessor调用postProcessAfterInitialization方法
IOC容器初始化成功
使用person对象的toString:Person [name=之后--赵六]
现在开始关闭容器!
【DiposibleBean接口】调用DiposibleBean.destory()
【destroy-method】调用<bean>的destroy-method属性指定的初始化方法

总结:

整个Bean的生命周期
1、实例化BeanFactoryPostProcessor实现类
2、执行BeanFactoryPostProcessor的postProcessBeanFactory修改XML对Bean配置的元信息
3、实例化BeanPostProcessor实现类
4、实例化InstantiationAwareBeanPostProcessorAdapter实现类
5、InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法,Bean实例化之前调用此方法

new Bean(),开始进行注入属性

6、InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法,可以修改Bean的属性信息
7、读取第二步BeanFactoryPostProcessor的postProcessBeanFactory方法中修改的XML对Bean的配置的元信息,修改Bean的属性
8、调用BeanNameAware的setBeanName方法,为Bean注入beanName(Bean的ID)
9、调用BeanFactoryAware的setBeanFactory,为Bean注入BeanFactory
10、BeanPostProcessor实现类调用接口方法postProcessBeforeInitialization对属性进行更改
11、InitializingBean实现类调用afterPropertiesSet()进行Bean的初始化方法
12、调用的init-method属性指定的初始化方法
13、BeanPostProcessor实现类接口方法postProcessAfterInitialization对属性进行更改

Bean的属性注入完毕

14、InstantiationAwareBeanPostProcessor实现类调用postProcessAfterInitialization方法,Bean实例化之后调用此方法
15、IOC容器初始化成功,可以调用容器的Bean使用了

下面是销毁动作

16、调用DiposibleBean接口的destory方法
17、调用<bean>的destroy-method属性指定的销毁方法

你可能感兴趣的:(Spring,MVC)