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

来源:互联网 发布:投资平台商业模式知乎 编辑:程序博客网 时间:2024/05/23 19:13

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;    }    // 通过<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属性指定的初始化方法");    }}

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配置信息

    <bean id="beanPostProcessor"         class="com.bean.MyBeanPostProcessor">    </bean>    <bean id="instantiationAwareBeanPostProcessor"         class="com.bean.MyInstantiationAwareBeanPostProcessor">    </bean>    <bean id="beanFactoryPostProcessor"         class="com.bean.MyBeanFactoryPostProcessor">    </bean>    <bean id="person1" class="com.bean.Person" init-method="myInit"        destroy-method="myDestory" scope="singleton">        <property name="name" value="aaa"></property>    </bean>

测试代码

    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=person1InstantiationAwareBeanPostProcessor调用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注入BeanFactory10、BeanPostProcessor实现类调用接口方法postProcessBeforeInitialization对属性进行更改11、InitializingBean实现类调用afterPropertiesSet()进行Bean的初始化方法12、调用<bean>的init-method属性指定的初始化方法13、BeanPostProcessor实现类接口方法postProcessAfterInitialization对属性进行更改Bean的属性注入完毕14、InstantiationAwareBeanPostProcessor实现类调用postProcessAfterInitialization方法,Bean实例化之后调用此方法15、IOC容器初始化成功,可以调用容器的Bean使用了下面是销毁动作16、调用DiposibleBean接口的destory方法17、调用<bean>的destroy-method属性指定的销毁方法
1 0
原创粉丝点击