定制Bean的行为

定制bean生命周期的行为

生命周期调用:通过实现InitializingBeanDisposableBean接口实现。

如果要减低代码和Spring框架的耦合程度,考虑使用注解。

org.springframework.beans.factory.InitializingBean接口用于初始化,只有一个方法:

void afterPropertiesSet() throws Exception;

在容器初始化bean并完成属性设置调用。建议使用JSR-250注解@PostConstruct。xml配置元数据文件中可以设置<bean/>元素的init-method属性:

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

org.springframework.beans.factory.DisposableBean接口用于销毁,只有一个方法:

void destroy() throws Exception;

当容器被销毁调用。建议使用JSR-250注解@PreDestroy。xml配置元数据文件中可以设置<bean/>元素的destroy-method属性:

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

destroy-method属性有一个特殊值:inferred,自动检测public的名为closeshutdown方法。
实现java.lang.AutoCloseablejava.io.Closeable接口的类也会被匹配。

默认初始化和销毁方法:

在xml配置模式下,可以给<beans/>元素设置:
default-init-method
default-destroy-method

参数是要调用的方法名。
属性来指定这个容器内的默认初始化或销毁方法。

这样在bean定义文件里写好方法就能自动调用。
容器内的bean可以覆盖它,通过设置init-methoddestroy-method属性。

将接口、默认方法和注解组合起来:

Spring提供三种方式控制bean的生命周期。
如果三种方式都被配置了不同的方法,则容器会按顺序全部执行。
如果配置了相同的方法,则只会执行一次。

调用顺序:
@PostConstruct@PreDestroy
InitializingBeanDisposableBean接口的方法,
init-methoddestroy-method属性声明的方法。

启动和关闭回调

Lifecycle接口定义了特定生命周期需求的方法:

public interface Lifecycle {

    void start();

    void stop();

    boolean isRunning();
}

任何Spring管理的对象都可以实现Lifecycle接口,当容器收到了start或stop就会调用相应的方法,
通过委托给LifecycleProcessor实现。LifecycleProcessor的定义:

public interface LifecycleProcessor extends Lifecycle {

    void onRefresh();

    void onClose();
}

org.springframework.context.Lifecycle不会在容器刷新时自动调用,可以考虑:
org.springframework.context.SmartLifecycle

注意:stop通知不保证会在销毁之前到达。

注意:stop通知不保证会在销毁之前到达。
shutdown动作时,Lifecycle类型bean会在销毁前收到stop信号。但是refresh动作只会调用销毁方法。

SmartLifecycle接口的定义:

public interface SmartLifecycle extends Lifecycle, Phased {

    boolean isAutoStartup();

    void stop(Runnable callback);
}

有时直接依赖不清楚,但是知道某个特定的类型应该在另一个类型之前启动,这时候就会用到Phased。
Phased接口定义:

public interface Phased {

    int getPhase();
}

启动和关闭时的调用顺序很重要,如果两个对象之间存在依赖关系,
则启动时依赖在需要它的对象之前启动,关闭时依赖在需要它的对象之后关闭。

启动时,最低的phase最先启动,关闭时,最低的phase最后关闭。
getPhase方法返回Integer.MIN_VALUE的对象最先启动和最后关闭。
MAX_VALUE就反过来,最后启动,最先关闭。
普通的Lifecycle类型对象调用getPhase返回0.
任何负数值意思是某个对象应该在所有的标准组件之前启动,在所有标准组件之后关闭。

SmartLifecycle接口的stop方法接受一个回调参数,在shutdown过程结束后调用。
在需要的时候可以作为异步关闭,因为默认实现DefaultLifecycleProcessor有一个超时属性,
让每个phase内的对象调用stop方法的回调参数。默认的超时为30秒,
可以定义一个名为lifecycleProcessor的bean注入到容器即可。

或者用xml配置:

<bean id="lifecycleProcessor" class="org.springframework.context.support.DefaultLifecycleProcessor">
    <!-- timeout value 属性单位是毫秒 -->
    <property name="timeoutPerShutdownPhase" value="10000"/>
</bean>

当容器刷新时会调用SmartLifecycle类型bean的isAutoStartup方法,如果返回true就会启动这个对象。

平稳关闭非web IoC容器:

向JVM注册一个hook。这样可以在程序结束运行时自动调用bean销毁方法,释放申请的资源。

ApplicationContextAwareBeanNameAware

当容器创建一个实现了
org.springframework.context.ApplicationContextAware
接口的bean时,被初始化的实例会获得一个指向创建它的容器的引用。

这个接口只有一个方法:

public interface ApplicationContextAware {
    void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}

同样的,可以在bean被创建之后将其改成指向别的容器的引用。

当容器创建一个实现了
orgorg.springframework.beans.factory.BeanNameAware
接口的bean时,被初始化的实例会获得一个指向定义它名称的字符串的引用。

这个接口只有一个方法:

public interface BeanNameAware {
    void setBeanName(String name) throws BeansException;
}

这个方法会在bean属性被设置之后调用。

留下评论

您的邮箱地址不会被公开。 必填项已用 * 标注