以下内容引用自http://wiki.jikexueyuan.com/project/spring/bean-life-cycle.html:
Bean的生命周期
当一个bean被实例化时,它可能需要执行一些初始化使它转换成可用状态。同样,当bean不再需要,并且从容器中移除时,可能需要做一些清除工作。
尽管还有一些在Bean初始化和销毁之间发生的动作,但是本章将只讨论两个重要的生命周期回调方法,它们在bean的初始化和销毁的时候是必需的。
为了定义安装和卸载一个bean,我们只要声明带有init-method和/或destroy-method参数 。init-method属性指定一个方法,在实例化bean时,立即调用该方法。同样,destroy-method属性指定一个方法,只有从容器中移除bean之后,才会调用该方法。
初始化回调
1、在基于代码实现中,org.springframework.beans.factory.InitializingBean接口指定一个单一的方法:
void afterPropertiesSet() throws Exception;
因此,你可以简单地实现上述接口并在afterPropertiesSet()方法中执行初始化工作,如下所示:
public class ExampleBean implements InitializingBean { public void afterPropertiesSet() { //代码逻辑 } }
2、在基于XML的配置元数据的情况下,你可以使用init-method属性来指定带有void无参数方法的名称。例如:
<bean id="exampleBean" class="examples.ExampleBean" init-method="init"/>
下面是类的定义:
public class ExampleBean { public void init() { //代码逻辑 } }
销毁回调
1、在基于代码实现中,org.springframework.beans.factory.DisposableBean接口指定一个单一的方法:
void destroy() throws Exception;
因此,你可以简单地实现上述接口并在destroy()方法中执行结束工作,如下所示:
public class ExampleBean implements DisposableBean { public void destroy() { // 代码逻辑 } }
2、在基于XML的配置元数据的情况下,你可以使用destroy-method属性来指定带有void无参数方法的名称。例如:
<bean id="exampleBean" class="examples.ExampleBean" destroy-method="destroy"/>
下面是类的定义:
public class ExampleBean { public void destroy() { // 代码逻辑 } }
说明:
1、如果在非web应用程序环境中使用Spring的IoC容器;例如在丰富的客户端桌面环境中;那么在JVM中你要注册关闭hook。这样做可以确保正常关闭,为了让所有的资源都被释放,可以在单个beans上调用destroy方法。
2、建议你不要使用InitializingBean或者DisposableBean的回调方法,因为XML配置在命名方法上提供了极大的灵活性。
例子:
pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.jsoft.testspring</groupId> <artifactId>testbeanlifecycle</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>testbeanlifecycle</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <!-- Spring Core --> <!-- http://mvnrepository.com/artifact/org.springframework/spring-core --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.1.4.RELEASE</version> </dependency> <!-- Spring Context --> <!-- http://mvnrepository.com/artifact/org.springframework/spring-context --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.1.4.RELEASE</version> </dependency> </dependencies> </project>
HelloWorld.java:
package com.jsoft.testspring.testbeanlifecycle; public class HelloWorld { private String messageString; public void setMessage(String message){ this.messageString = message; } public void getMessage(){ System.out.println(this.messageString); } public void initCustom(){ System.out.println("初始化"); } public void destroyCustom(){ System.out.println("销毁"); } }
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.jsoft.testspring.testbeanlifecycle.HelloWorld" init-method="initCustom" destroy-method="destroyCustom"> <property name="Message" value="Hello World!"></property> </bean> </beans>
App.java:
package com.jsoft.testspring.testbeanlifecycle; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * Hello world! * */ public class App { public static void main( String[] args ) { AbstractApplicationContext abstractApplicationContext = new ClassPathXmlApplicationContext("beans.xml"); HelloWorld helloWorld = (HelloWorld)abstractApplicationContext.getBean("helloWorld"); helloWorld.getMessage(); abstractApplicationContext.registerShutdownHook();//因为在AbstractApplicationContext类中才有registerShutdownHook()方法 } }
测试结果:
还有一种实现方式:
基于注解的方式实现,使用@PostConstruct和@PreDestroy实现初始化和销毁。
HelloWorld.java加入如下代码:
@PostConstruct public void initPost(){ System.out.println("@ init"); } @PreDestroy public void destroyPre(){ System.out.println("@ destroy"); }
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" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <bean id="helloWorld" class="com.jsoft.testspring.testbeanlifecycle.HelloWorld" init-method="initCustom" destroy-method="destroyCustom"> <property name="Message" value="Hello World!"></property> </bean> <context:annotation-config/> </beans>
测试工程:https://github.com/easonjim/5_java_example/tree/master/springtest/test5/testbeanlifecycle