Bean的生命周期表示Bean有实例化、初始化、使用以及销毁的过程。
在Bean的整个生命周期中存在一系列的行为,这一节我们只讨论两个重要的方法,一个在初始化的时候,一个是在实例被销毁的时候。
为了定义一个Bean的实例化和销毁的时刻需要做的事情,可以使用initmethod和destroymethod参数。init-method属性指明的方法在bean被实例化后立刻被执行。相似的destroy-method属性设置的方法会在bean被销毁之前被执行
Initialization callbacks
org.springframework.beans.factory.InitializingBean
接口实现了一个单一的方法:
void afterPropertiesSet() throws Exception;
因此,你可以实现上面的接口,并且初始化的工作可以在afterPropertiesSet()方法中执行:
public class ExampleBean implements InitializingBean {
public void afterPropertiesSet() {
// do some initialization work
}
}
当然也可以不去实现上面接口,在基于xml的配置中,你可以使用下面的配置执行初始化的方法。比如:
<bean id = "exampleBean" class = "examples.ExampleBean" init-method = "init"/>
在class中的定义如下:
public class ExampleBean {
public void init() {
// do some initialization work
}
}
Destruction callbacks
org.springframework.beans.factory.DisposableBean
接口实现了一个唯一的方法:
void destroy() throws Exception;
因此和初始化一样,可以实现上面的接口来完成Destruction callback,比如:
public class ExampleBean implements DisposableBean {
public void destroy() {
// do some destruction work
}
}
当然,也可以不使用上面的接口,在XML的配置中,可以想下面这样完成销毁的回调处理:
<bean id = "exampleBean" class = "examples.ExampleBean" destroy-method = "destroy"/>
在类中的定义:
public class ExampleBean {
public void destroy() {
// do some destruction work
}
}
如果在非web的application的环境中使用了Spring IoC容器,比如在一个rich client desktop envirenment
中,你可以在JVM中注册一个shutdown hook
。这么做可以确保优雅的释放各种资源,优雅的结束应用程序。
推荐不要实现上面的接口,可以在xml中进行配置,因为配置更加灵活。
Example
HelloWoeld.java
package com.soygrow;
public class HelloWorld {
private String message;
public void setMessage(String message) {
this.message = message;
}
public void getMessage() {
System.out.println("Your Message : " + message);
}
public void init() {
System.out.println("init function ...");
}
public void destroy() {
System.out.println("destroy function ...");
}
}
MainApp.java
package com.soygrow;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
ApplicationContext context =
new ClassPathXmlApplicationContext("Beans.xml");
HelloWorld helloWorld = (HelloWorld) context.getBean("helloWorld");
helloWorld.getMessage();
helloWorld.setMessage("singleton test.");
HelloWorld helloWorld1 = (HelloWorld) context.getBean("helloWorld");
helloWorld1.getMessage();
((ClassPathXmlApplicationContext) context).close();
}
}
Beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="helloWorld" class="com.soygrow.HelloWorld" init-method="init" destroy-method="destroy">
<property name="message" value="Hello Soygrow!"/>
</bean>
</beans>
如果一切正常,运行结果如下:
init function ...
Your Message : Hello Soygrow!
Your Message : singleton test.
destroy function ...
Default initialization and destroy methods
如果你有很多的init-method和destroy-method方法,而且都是相同的名称,那么可以使用default-init-method
和default-destroy-method
,那么可以配置成如下的样子:
<beans xmlns = "http://www.springframework.org/schema/beans"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"
default-init-method = "init"
default-destroy-method = "destroy">
<bean id = "..." class = "...">
<!-- collaborators and configuration for this bean go here -->
</bean>
</beans>
遇到的问题
这里遇到的问题是可能你没有执行最后的destroy方法,那可能因为你没有结束context,所以需要主动关闭context。方法如下:
第一种可以像我上面那样做强制转换就会有close方法;第二种可以使用下面的代码进行操作:
AbstractApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
......
// 结束context,才会调用destroy方法
context.registerShutdownHook();
Spring教程专栏地址:http://blog.csdn.net/column/details/19452.html