生命周期调用:通过实现InitializingBean和DisposableBean接口实现。
如果要减低代码和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注解
。xml配置元数据文件中可以设置<bean/>元素的destroy-method属性:@PreDestroy
<bean id="exampleInitBean" class="examples.ExampleBean" destroy-method="cleanup"/>
destroy-method属性有一个特殊值:inferred,自动检测public的名为close
或shutdown
方法。
实现java.lang.AutoCloseable
或java.io.Closeable
接口的类也会被匹配。
默认初始化和销毁方法:
在xml配置模式下,可以给<beans/>元素设置:
default-init-method
default-destroy-method
参数是要调用的方法名。
属性来指定这个容器内的默认初始化或销毁方法。
这样在bean定义文件里写好方法就能自动调用。
容器内的bean可以覆盖它,通过设置init-method
和destroy-method
属性。
将接口、默认方法和注解组合起来:
Spring提供三种方式控制bean的生命周期。
如果三种方式都被配置了不同的方法,则容器会按顺序全部执行。
如果配置了相同的方法,则只会执行一次。
调用顺序:
@PostConstruct或@PreDestroy,
InitializingBean或DisposableBean接口的方法,init-method
和destroy-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销毁方法,释放申请的资源。
ApplicationContextAware
和BeanNameAware
当容器创建一个实现了
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属性被设置之后调用。