码迷,mamicode.com
首页 > 编程语言 > 详细

Spring Bean的生命周期详解

时间:2018-07-02 23:35:30      阅读:346      评论:0      收藏:0      [点我收藏+]

标签:text   掌握   npos   throw   接口   logs   getc   ext   tcl   

Spring Bean的生命周期详解

  Spring IoC容器的本质目的就是为了管理Bean,对于Bean而言,在容器中存在其生命周期,它的初始化和销毁也需要一个过程,下面主要对其生命周期进行一个详解的解释。生命周期主要是为了了解Spring IoC容器初始化和销毁Bean的过程,通过下图即可以掌握Spring IoC容器初始化与销毁Bean的过程。

技术分享图片

  

  通过上图,我们首先可以看到生命周期的步骤。

  1)如果Bean实现了接口 BeanNameAware 的 setBeanName 方法,那么它就会调用这个方法。

  2)如果Bean实现了接口 BeanfactoryAware 的 setBeanFactory 方法,那么它就会调用这个方法。

  3)如果Bean实现了接口 ApplicationContextAware 的 setApplicationContext方法,且 Spring IoC容器也必须是一个 ApplicationContext 接口的实现类,那么才会调用这个方法,否则是不调用的。

  4)如果 Bean 实现了接口 BeanPostProcessor 的 postProcessBeforeInitialization 方法,那么它就会调用这个方法。

  5)如果 Bean 实现了接口 BeanFactoryPostProcessor 的 afterPropertiesSet 方法,那么它就会调用这个方法。

  6)如果 Bean 自定义了初始化方法,它就会调用已定义的初始化方法。

  7)如果 Bean 实现了接口 BeanPostProcessor 的 postProcessAfterInitialization 方法,完成了这些调用,这时候Bean 就完成了初始化,那么Bean 就生存在 Spring IoC容器中,使用者就可以从中获取Bean的服务。

  

  当服务器正常关闭,或者遇到其他关闭Spring IoC容器的事件,它就会调用对应的方法完成Bean的销毁,其步骤如下:

  1)首先如果Bean实现了接口 DisposableBean 的 destory 方法,那么就会调用它。

  2)如果定义了自定义销毁方法,那么就会调用它。

 

  需要主要的是,上述的关于生命周期的接口,大部分都是针对单个Bean而言的,BeanPostProcessor 接口是针对所有Bean而言的,当一个Bean实现了上述的接口,只需要在Spring IoC容器中定义它就可以,Spring IoC容器会自动识别,并且按顺序执行,下面对BeanPostProcessor 接口进行实现和测试。

 

BeanPostProcessor 的实现类,处理Spring IoC容器所有的Bean

package com.cnblogs.demrystv.bean;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

public class BeanPostProcessorImpl implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("【" + bean.getClass().getSimpleName() + "】对象" + beanName + "开始实例化");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("【" + bean.getClass().getSimpleName() + "】对象" + beanName + "实例化完成");
        return bean;
    }

}

 

测试生命周期

package com.cnblogs.demrystv.pojo;

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.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class JuiceMaker implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean {
    private String beverageShop = null;
    private Source source = null;

    public String getBeverageShop() {
        return beverageShop;
    }

    public void setBeverageShop(String beverageShop) {
        this.beverageShop = beverageShop;
    }

    public Source getSource() {
        return source;
    }

    public void setSource(Source source) {
        this.source = source;
    }

    public String makeJuice() {
        String juice = "这是一杯由" + beverageShop + "饮品店,提供的" + source.getSize() + source.getSugar() + source.getFruit();
        return juice;
    }

    public void init() {
        System.out.println("【" + this.getClass().getSimpleName() + "】执行自定义初始化方法");
    }

    public void destroy() {
        System.out.println("【" + this.getClass().getSimpleName() + "】执行自定义销毁方法");
    }

    @Override
    public void setBeanName(String arg0) {
        System.out.println("【" + this.getClass().getSimpleName() + "】调用BeanNameAware接口的setBeanName方法");

    }

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

    @Override
    public void setApplicationContext(ApplicationContext arg0) throws BeansException {
        System.out.println(
                "【" + this.getClass().getSimpleName() + "】调用ApplicationContextAware接口的setApplicationContext方法");
    }

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

 

同时,为了使自定义的方法生效,应该在xml中声明自定义的初始化和销毁方法的Bean

  <!--BeanPostProcessor定义 -->
    <bean id="beanPostProcessor" class="com.cnblogs.demrystv.bean.BeanPostProcessorImpl" />

    <bean id="source" class="com.cnblogs.demrystv.pojo.Source">
        <property name="fruit" value="橙汁" />
        <property name="sugar" value="少糖" />
        <property name="size" value="大杯" />
    </bean>

    <bean id="juiceMaker" class="com.cnblogs.demrystv.pojo.JuiceMaker2"
        destroy-method="destroy" init-method="init">
        <property name="beverageShop" value="贡茶" />
        <property name="source" ref="source" />
    </bean>

 

配置完成后,测试 Spring Bean的生命周期

ClassPathXmlApplicationContext ctx = 
                new ClassPathXmlApplicationContext("spring-cfg.xml");
        JuiceMaker juiceMaker = (JuiceMaker) ctx.getBean("juiceMaker");
        System.out.println(juiceMaker.makeJuice());
        ctx.close();

 

运行它,可以得到下面的日志:

【Source】对象source开始实例化
【Source】对象source实例化完成
【JuiceMaker】调用BeanNameAware接口的setBeanName 方法
【JuiceMaker】调用BeanFactoryAware接口的setBeanFactory方法
【JuiceMaker】调用ApplicationContextAware 接口的setApplicationContext方法
【JuiceMaker】对象juicemaker开始实例化
【JuiceMaker】调用InitializingBean 接口的afterpropertiesSet方法
【JuiceMaker】执行自定义初始化方法
【JuiceMaker】对象juiceMaker 实例化完成
 这是一杯由贡茶饮品店,提供的大杯少糖橙汁
【JuiceMaker】调用DisposableBean接口的destory方法
【JuiceMaker】执行自定义销毁方法

 

  从日志中就可以发现所有的生命周期的方法都已经被执行了,从打印的日志可以看到,BeanPostProcessor针对全部Bean,这样就可以利用生命周期来完成一些需要自定义的初始化和销毁Bean的行为。

 

Spring Bean的生命周期详解

标签:text   掌握   npos   throw   接口   logs   getc   ext   tcl   

原文地址:https://www.cnblogs.com/Demrystv/p/9256351.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!