3.4. 自定义bean的本质特征
3.4.1. 生命周期接口
Spring提供了一些标志接口,用来改变BeanFactory中的bean的行为。 它们包括InitializingBean和DisposableBean。 实现这些接口将会导致BeanFactory调用前一个接口的afterPropertiesSet()方法, 调用后一个接口destroy()方法,从而使得bean可以在初始化和析构后做一些特定的动作。
在内部,Spring使用BeanPostProcessors 来处理它能找到的标志接口以及调用适当的方法。 如果你需要自定义的特性或者其他的Spring没有提供的生命周期行为, 你可以实现自己的 BeanPostProcessor。关于这方面更多的内容可以看这里: 第 3.7 节 “使用BeanPostprocessors定制bean”。
所有的生命周期的标志接口都在下面叙述。在附录的一节中,你可以找到相应的图, 展示了Spring如何管理bean;那些生命周期的特性如何改变你的bean的本质特征以及它们如何被管理。
3.4.1.1. InitializingBean / init-method
实现org.springframework.beans.factory.InitializingBean 接口允许一个bean在它的所有必须的属性被BeanFactory设置后, 来执行初始化的工作。InitializingBean接口仅仅制定了一个方法:
* Invoked by a BeanFactory after it has set all bean properties supplied
* (and satisfied BeanFactoryAware and ApplicationContextAware).
* <p>This method allows the bean instance to perform initialization only
* possible when all bean properties have been set and to throw an
* exception in the event of misconfiguration.
* @throws Exception in the event of misconfiguration (such
* as failure to set an essential property) or if initialization fails.
*/
void afterPropertiesSet() throws Exception;注意:通常InitializingBean接口的使用是能够避免的(而且不鼓励,因为没有必要把代码同Spring耦合起来)。Bean的定义支持指定一个普通的初始化方法。在使用XmlBeanFactory的情况下,可以通过指定init-method属性来完成。 举例来说,下面的定义:
<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。
3.4.1.2. DisposableBean / destroy-method
实现org.springframework.beans.factory.DisposableBean接口允许一个bean, 可以在包含它的BeanFactory销毁的时候得到一个回调。DisposableBean也只指定了一个方法:
/**
* Invoked by a BeanFactory on destruction of a singleton.
* @throws Exception in case of shutdown errors.
* Exceptions will get logged but not rethrown to allow
* other beans to release their resources too.
*/
void destroy() throws Exception;
注意:通常DisposableBean接口的使用能够避免的(而且是不鼓励的,因为它不必要地将代码耦合于Spring)。 Bean的定义支持指定一个普通的析构方法。在使用XmlBeanFactory使用的情况下,它是通过 destroy-method属性完成。 举例来说,下面的定义:
<bean id="exampleInitBean" class="examples.ExampleBean" destroy-method="destroy"/>
public class ExampleBean {
public void cleanup() {
// do some destruction work (like closing connection)
}
}同下面的完全一样:
<bean id="exampleInitBean" class="examples.AnotherExampleBean"/>
public class AnotherExampleBean implements DisposableBean {
public void destroy() {
// do some destruction work
}
}但却不把代码耦合于Spring。
重要的提示:当以portotype模式部署一个bean的时候,bean的生命周期将会有少许的变化。 通过定义,Spring无法管理一个non-singleton/prototype bean的整个生命周期, 因为当它创建之后,它被交给客户端而且容器根本不再留意它了。 当说起non-singleton/prototype bean的时候,你可以把Spring的角色想象成“new”操作符的替代品。 从那之后的任何生命周期方面的事情都由客户端来处理。BeanFactory中bean的生命周期将会在第 3.4.1 节 “生命周期接口” 一节中有更详细的叙述 .
3.4.1. 生命周期接口
Spring提供了一些标志接口,用来改变BeanFactory中的bean的行为。 它们包括InitializingBean和DisposableBean。 实现这些接口将会导致BeanFactory调用前一个接口的afterPropertiesSet()方法, 调用后一个接口destroy()方法,从而使得bean可以在初始化和析构后做一些特定的动作。
在内部,Spring使用BeanPostProcessors 来处理它能找到的标志接口以及调用适当的方法。 如果你需要自定义的特性或者其他的Spring没有提供的生命周期行为, 你可以实现自己的 BeanPostProcessor。关于这方面更多的内容可以看这里: 第 3.7 节 “使用BeanPostprocessors定制bean”。
所有的生命周期的标志接口都在下面叙述。在附录的一节中,你可以找到相应的图, 展示了Spring如何管理bean;那些生命周期的特性如何改变你的bean的本质特征以及它们如何被管理。
3.4.1.1. InitializingBean / init-method
实现org.springframework.beans.factory.InitializingBean 接口允许一个bean在它的所有必须的属性被BeanFactory设置后, 来执行初始化的工作。InitializingBean接口仅仅制定了一个方法:
* Invoked by a BeanFactory after it has set all bean properties supplied
* (and satisfied BeanFactoryAware and ApplicationContextAware).
* <p>This method allows the bean instance to perform initialization only
* possible when all bean properties have been set and to throw an
* exception in the event of misconfiguration.
* @throws Exception in the event of misconfiguration (such
* as failure to set an essential property) or if initialization fails.
*/
void afterPropertiesSet() throws Exception;注意:通常InitializingBean接口的使用是能够避免的(而且不鼓励,因为没有必要把代码同Spring耦合起来)。Bean的定义支持指定一个普通的初始化方法。在使用XmlBeanFactory的情况下,可以通过指定init-method属性来完成。 举例来说,下面的定义:
<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。
3.4.1.2. DisposableBean / destroy-method
实现org.springframework.beans.factory.DisposableBean接口允许一个bean, 可以在包含它的BeanFactory销毁的时候得到一个回调。DisposableBean也只指定了一个方法:
/**
* Invoked by a BeanFactory on destruction of a singleton.
* @throws Exception in case of shutdown errors.
* Exceptions will get logged but not rethrown to allow
* other beans to release their resources too.
*/
void destroy() throws Exception;
注意:通常DisposableBean接口的使用能够避免的(而且是不鼓励的,因为它不必要地将代码耦合于Spring)。 Bean的定义支持指定一个普通的析构方法。在使用XmlBeanFactory使用的情况下,它是通过 destroy-method属性完成。 举例来说,下面的定义:
<bean id="exampleInitBean" class="examples.ExampleBean" destroy-method="destroy"/>
public class ExampleBean {
public void cleanup() {
// do some destruction work (like closing connection)
}
}同下面的完全一样:
<bean id="exampleInitBean" class="examples.AnotherExampleBean"/>
public class AnotherExampleBean implements DisposableBean {
public void destroy() {
// do some destruction work
}
}但却不把代码耦合于Spring。
重要的提示:当以portotype模式部署一个bean的时候,bean的生命周期将会有少许的变化。 通过定义,Spring无法管理一个non-singleton/prototype bean的整个生命周期, 因为当它创建之后,它被交给客户端而且容器根本不再留意它了。 当说起non-singleton/prototype bean的时候,你可以把Spring的角色想象成“new”操作符的替代品。 从那之后的任何生命周期方面的事情都由客户端来处理。BeanFactory中bean的生命周期将会在第 3.4.1 节 “生命周期接口” 一节中有更详细的叙述 .