美文网首页
9.3.3、Bean的生命周期

9.3.3、Bean的生命周期

作者: john_leventon | 来源:发表于2018-11-11 21:31 被阅读0次

    1、Bean的作用域

    在配置文件中用属性scope标注

    (1)标注scope为singleton或者缺省scope属性的Bean在ApplicationContext(IOC容器为BeanFactory非ApplicationContext实现类则不会)启动时就会自动实例化,并且从容器启动到销毁只存在一个实例,容器负责这个实例的全部生命周期的管理。

    (2)标注scope为prototype的Bean只在IOC容器的getBean()方法被调用时才会进行实例化,并且每次调用该方法返回的都是不同的实例。

    (3)标注socpe为request的Bean对于每一次request都将产生不同Bean实例,并且在一次request结束后Bean的实例将销毁。

    (4)标注scope为session的Bean对于每次session会话都只产生一个Bean实例,并且在session失效后自动销毁。

    (5)当一个bean的作用域为Global Session,表示在一个全局的HTTP Session中,一个bean定义对应一个实例。典型情况下,仅在使用portlet context的时候有效。该作用域仅在基于web的Spring ApplicationContext情形下有效。

    需要注意的是,后面三种作用域只针对web应用

    2、Bean的生命周期

    Bean实例生命周期的执行过程如下:

    Spring对bean进行实例化,默认bean是单例;

    Spring对bean进行依赖注入;

    如果bean实现了BeanNameAware接口,spring将bean的id传给setBeanName()方法;

    如果bean实现了BeanFactoryAware接口,spring将调用setBeanFactory方法,将BeanFactory实例传进来;

    如果bean实现了ApplicationContextAware接口,它的setApplicationContext()方法将被调用,将应用上下文的引用传入到bean中;

    如果bean实现了BeanPostProcessor接口,它的postProcessBeforeInitialization方法将被调用;

    如果bean实现了InitializingBean接口,spring将调用它的afterPropertiesSet接口方法,类似的如果bean使用了init-method属性声明了初始化方法,该方法也会被调用;

    如果bean实现了BeanPostProcessor接口,它的postProcessAfterInitialization接口方法将被调用;

    此时bean已经准备就绪,可以被应用程序使用了,他们将一直驻留在应用上下文中,直到该应用上下文被销毁;

    若bean实现了DisposableBean接口,spring将调用它的destroy()接口方法。同样的,如果bean使用了destroy-method属性声明了销毁方法,则该方法被调用;

    不管何种作用域,容器都会调用所有对象的初始化生命周期回调方法。但对prototype而言,任何配置好的析构生命周期回调方法都将不会被调用(在scope为prototype的Bean中配置destroy-method属性无效)。清除prototype作用域的对象并释放任何prototype bean所持有的昂贵资源(如数据库连接资源),都是客户端代码的职责(让Spring容器释放被prototype作用域bean占用资源的一种可行方式是,通过使用bean的后置处理器,该处理器持有要被清除的bean的引用)。

    例子:

    定义两个类Source、JuiceMaker,都实现BeanNameAware、BeanFactoryAware、ApplicationContextAware、InitializingBean接口。

    定义类MyPostProcessorImpl实现BeanPostProcessor接口、MyDisposableImpl实现DisposableBean接口

    代码如下:

    Source:

    public class Source implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean{

    private String fruit;

    private String sugar;

    private String size;

    /**getter and setter*/

    .....

    public void setBeanName(String name) {

    System.out.println("【Source】调用BeanNameAware接口的setBeanName方法");

    }

    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {

    System.out.println("【Source】调用BeanFactory接口的setBeanFactory方法");

    }

    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {

    System.out.println("【Source】调用ApplicationContext接口的setApplicationContext方法");

    }

    public void afterPropertiesSet() throws Exception {

    System.out.println("【Source】调用InitializingBean接口的afterPropertiesSet方法");

    }

    //自定义初始化和销毁方法

    public void init() {

    System.out.println("【Source】调用自定义初始化方法初始化");

    }

    public void destroy() {

    System.out.println("【Source】调用自定义销毁方法");

    }

    }

    JuiceMaker的代码和Source类似就不贴出来了,下面来看MyPostProcessorImpl和MyDisposableImpl的代码:

    MyPostProcessorImpl:

    public class MyPostProcessorImpl implements BeanPostProcessor{

    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {

    System.out.println("【MyPostProcessor】" + bean.getClass().getSimpleName() + "的对象" + beanName + "开始初始化");

    return bean;

    }

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

    System.out.println("【MyPostProcessor】" + bean.getClass().getSimpleName() + "的对象" + beanName + "初始化完成");

    return bean;

    }

    }

    MyDisposableImpl:

    public class MyDisposableImpl implements DisposableBean{

    public void destroy() throws Exception {

      System.out.println("【MyDisposableImpl】调用DisposableBean接口destroy方法");

    }

    }

    在配置文件中配置bean:

    <?xml version="1.0" encoding="UTF-8"?>

    <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-4.0.xsd">

    <bean id="source" class="spring.chapter9.ioc.Source" init-method="init" destroy-method="destroy">

    <property name="fruit" value="橙子" ></property>

    <property name="sugar" value="三勺" />

    <property name="size"  value="大杯" />

    </bean>

    <bean id="juiceMaker" class="spring.chapter9.ioc.JuiceMaker" init-method="init" destroy-method="destroy">

        <property name="shopName" value="布拉格" />

        <property name="source"  ref="source" />

    </bean>

    <bean id="beanPostProcessor" class="spring.chapter9.lifecycle.MyPostProcessorImpl" />

    <bean id="beanDisposable" class="spring.chapter9.lifecycle.MyDisposableImpl" />

    </beans>

    注意加粗的部分,分别给bean指定自定义的初始化和销毁方法.

    测试:

    public class Test {

    private static ApplicationContext ctx;

    public static void main(String[] args) {

    ctx =

    new ClassPathXmlApplicationContext("classpath:spring-cfg-ioc.xml");

    JuiceMaker juiceMaker = (JuiceMaker) ctx.getBean("juiceMaker");

    juiceMaker.make();

    }

    由此可见BeanNameAware、BeanFactoryAware、ApplicationContextAware、InitializingBean接口都是针对单个Bean而言的,而BeanPostProcessor接口则是针对每一个Bean(当然不包括实现了这个接口的Bean本身)。DisposableBean是针对Spring IoC容器的。

    另外需要注意的是,afterPropertiesSet方法执行完后,如果没有自定义初始化方法,那么Bean的初始化和依赖注入已经完成了。

    相关文章

      网友评论

          本文标题:9.3.3、Bean的生命周期

          本文链接:https://www.haomeiwen.com/subject/wueffqtx.html