生命周期回调(Lifecycle callbacks)

为参与bean生命周期的容器管理,你可以实现Spring的InitializingBean和DisposableBean接口。对于前者容器调用afterPropertiesSet()方法,对后者调用destroy()方法,允许bean在你的bean的初始化和销毁上执行某些动作。

注意:JSR-250的@PostConstruct 和@PreDestroy注解被认为是在现在的Spring的应用中接受生命周期回调的最好实践。使用这些注解意味着你的beans不会耦合到你的Spring的规范接口中。

如果你不想使用注解但是了又不想与Spring 接口耦合,考虑使用在对象定义元数据时使用init-method和destory-method 属性。

在内部,Spring框架使用BeanPostProcessor实现处理任何回调接口,你可以发现和调用那些可用的方法。如果你需要定制化功能或者其他的生命周期行为(Spring出箱不提供的),你可以自己实现BeanPostProcessor。

对于额外的初始化和销毁回调函数,Spring管理的对象也可能实现了Lifecycle接口,这样 那些对象可以参与到启动和关闭处理,如同容器的自己生命周期驱动运行一样。

生命周期回调接口在这里描述

初始化回调函数

org.springframework.beans.factory.InitializingBean接口允许bean的必须属性都被容器设置后执行初始化工作。这个接口指定了一个方法:

void afterPropertiesSet() throws Exception;

推荐不要直接使用

InitializingBean接口,会与Spring耦合。作为替代,使用

@PostConstruct注解或者指定一个POJO初始化方法。在基于XML配置元数据的情况下,使用init-method属性指定方法名,其有一个void 的非参数方法签名。如下例子:

<bean id="exampleInitBean" class="examples.ExampleBean" init-method="init"/>

public class ExampleBean {

    public void init() {
        // do some initialization work
    }

}

与下面的效果一样:

<bean id="exampleInitBean" class="examples.AnotherExampleBean"/>

public class AnotherExampleBean implements InitializingBean {

    public void afterPropertiesSet() {
        // do some initialization work
    }

}

但不会与Spring耦合。

销毁回调函数

实现org.springframework.beans.factory.DisposableBean接口,允许一个bean当容器需要其销毁时获取一个回调。DisposableBean接口指定了一个方法:

void destroy() throws Exception;

建议不使用

DisposableBean回调接口,因为其不与Spring耦合。使用

@PreDestroy注解或者指定一个普通方法,但能由bean定义支持。基于XML配置的元数据,你使用<bean/>元素的destory-method属性。例如,下面的定义:

<bean id="exampleInitBean" class="examples.ExampleBean" destroy-method="cleanup"/>

public class ExampleBean {

    public void cleanup() {
        // do some destruction work (like releasing pooled connections)
    }

}

与下面效果相同:

<bean id="exampleInitBean" class="examples.AnotherExampleBean"/>

public class AnotherExampleBean implements DisposableBean {

    public void destroy() {
        // do some destruction work (like releasing pooled connections)
    }

}

但是了不会与Spring耦合。

默认的初始化和销毁方法(Default initialization and destroy methods)

当你写初始化和销毁方法,而不使用Spring指定的InitializingBean 和 DisposableBean的回调接口,一般你采用init(),intialize(),dispose()方法命名。理想情况下,整个工程中的生命周期回调方法都是统一命名,这样所有的开发者使用相同的方法名并保证一致性。

你可以配置Spring容器来查找每个bean上的初始化和销毁回调方法名。这意味着,作为一个应用开发者,可以写你的应用类和调用一个名为init()的初始化回调方法,而不需要为每个bean配置init-method属性。Spring IoC容器在bean每次创建的时候调用那个方法。

假定你的初始化回调方法命名为init(),而你的销毁回调方法命名为destory()。你的类就会与下面的类似。

public class DefaultBlogService implements BlogService {

    private BlogDao blogDao;

    public void setBlogDao(BlogDao blogDao) {
        this.blogDao = blogDao;
    }

    // this is (unsurprisingly) the initialization callback method
    public void init() {
        if (this.blogDao == null) {
            throw new IllegalStateException("The [blogDao] property must be set.");
        }
    }

}

<beans default-init-method="init">

    <bean id="blogService" class="com.foo.DefaultBlogService">
        <property name="blogDao" ref="blogDao" />
    </bean>

</beans>