生命周期回调(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>