Spring 容器中的 Bean 是有生命周期的,spring 允許 Bean 在初始化完成後以及銷毀前執行特定的操作。 下面是常用的三種指定特定操作的方法:
- 通過實作InitializingBean/DisposableBean 接口來定制初始化之後/銷毀之前的操作方法;
- 通過<bean> 元素的init-method/destroy-method屬性指定初始化之後 /銷毀之前調用的操作方法;
- 在指定方法上加上@PostConstruct或@PreDestroy注解來制定該方法是在初始化之後還是銷毀之前調用。
這幾種配置方式,執行順序是怎樣的呢?我們通過例子來研究下:
Bean的列子類:InitBeanAndDestroyBean.java
package com.chenfeng.xiaolyuh.entity;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
public class InitBeanAndDestroyBean implements InitializingBean, DisposableBean {
public String say() {
return "Hello!" + this.getClass().getName();
}
public InitBeanAndDestroyBean() {
System.out.println("執行InitBeanAndDestroyBean構造方法");
}
@Override
public void destroy() throws Exception {
System.out.println("接口-執行InitBeanAndDestroyBeanTest:destroy方法");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("接口-執行InitBeanAndDestroyBeanTest:afterPropertiesSet方法");
}
@PostConstruct
public void postConstructstroy() {
System.out.println("注解-執行InitBeanAndDestroyBeanTest:preDestroy方法");
}
@PreDestroy
public void preDestroy() {
System.out.println("注解--執行InitBeanAndDestroyBeanTest:preDestroy方法");
}
public void initMethod() {
System.out.println("XML配置-執行InitBeanAndDestroyBeanTest:init-method方法");
}
public void destroyMethod() {
System.out.println("XML配置-執行InitBeanAndDestroyBeanTest:destroy-method方法");
}
}
Spring配置類MyConfig.java
@Configuration // 聲明成配置檔案
@ComponentScan("com.chenfeng.xiaolyuh") // 掃描包
public class MyConfig {
// 測試Bean的幾種初始化和銷毀方式,和執行順序
@Bean(initMethod="initMethod", destroyMethod="destroyMethod")
public InitBeanAndDestroyBean initBeanAndDestroyBean() {
return new InitBeanAndDestroyBean();
}
}
測試類SpringIocTest.java
public class SpringIocTest {
// 使用容器
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class, CatEntity.class);
@Test
public void contextTest() {
// 測試Bean的三種初始化、銷毀方式和執行順序
System.out.println(context.getBean(InitBeanAndDestroyBean.class));
}
@After
public void closeContext() {
context.close();
}
}
列印結果:
三月 10, 2017 1:47:02 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
資訊: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@3b22cdd0: startup date [Fri Mar 10 13:47:02 CST 2017]; root of context hierarchy
執行InitBeanAndDestroyBean構造方法
注解-執行InitBeanAndDestroyBeanTest:preDestroy方法
接口-執行InitBeanAndDestroyBeanTest:afterPropertiesSet方法
XML配置-執行InitBeanAndDestroyBeanTest:init-method方法
三月 10, 2017 1:47:02 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
資訊: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@3b22cdd0: startup date [Fri Mar 10 13:47:02 CST 2017]; root of context hierarchy
注解--執行InitBeanAndDestroyBeanTest:preDestroy方法
接口-執行InitBeanAndDestroyBeanTest:destroy方法
XML配置-執行InitBeanAndDestroyBeanTest:destroy-method方法
- Bean在執行個體化的過程中:Constructor > @PostConstruct >InitializingBean > init-method
- Bean在銷毀的過程中:@PreDestroy > DisposableBean > destroy-method