7.9.2: Bean 销毁之前的行为

本文介绍如何在Spring框架中定制Bean的销毁行为,包括使用destroy-method属性及实现DisposableBean接口两种方式,并通过示例代码展示了如何注册关闭钩子来确保容器优雅关闭。

与定制初始化行为相似,Spring也提供两种方法定制Bean实例销毁之前的行为

① 使用destroy-method属性:

destroy-method属性指定某个方法在Bean销毁之前被自动执行。使用这种方式,不需要将代码与Spring的接口耦合,代码污染小。

② 实现DisposableBean接口:

该接口提供了一个方法,void destroy( ) throws Exception,该方法就是Bean实例被销毁之前应该执行的方法。

Axe.java :

public interface Axe {
	public String chop();
}
Person.java :

public interface Person {
	public void useAxe();
}
SteelAxe.java :

public class SteelAxe implements Axe {

	@Override
	public String chop() {
		return "钢斧砍柴真快";
	}

	public SteelAxe() {
		System.out.println("Spring实例化依赖Bean:SteelAxe实例...");
	}
	
	
}
Chinese.java :

public class Chinese implements Person,DisposableBean {
	
	private Axe axe;
	
	public Chinese() {
		System.out.println("Spring实例化主调Bean:Chinese实例...");
	}

	public void setAxe(Axe axe) {
		System.out.println("Spring执行依赖关系注入...");
		this.axe = axe;
	}

	@Override
	public void useAxe() {
		System.out.println(axe.chop());
	}

	public void close(){
		System.out.println("正在执行销毁之前的方法close...");
	}

	@Override
	public void destroy() throws Exception {
		System.out.println("正在执行销毁之前的方法destroy...");
	}
	

}
bean.xml核心配置:

 <bean id="chinese" class="com.bean.Chinese" destroy-method="close">
    <property name="axe" ref="steelAxe"></property>
 </bean>
  
 <bean id="steelAxe" class="com.bean.SteelAxe"/>
Test.java :

public class Test {

	public static void main(String[] args) {
		
		AbstractApplicationContext ctx=new ClassPathXmlApplicationContext("bean.xml");
		Person p=(Person) ctx.getBean("chinese");
		p.useAxe();
		ctx.registerShutdownHook();
	}

}
运行Test.java,控制台输出:


singleton 作用域的Bean通常会随容器的关闭而销毁,但问题是:ApplicationContext容器在什么时候关闭呢?在基于web的ApplicationContext实现中,系统已经提供了相应的代码保证关闭web应用时恰当地关闭Spring容器。

如果处于一个非web应用的环境下,为了让Spring容器优雅地关闭,并调用singleton Bean上的相应析构回调方法,则需要在JVM虚拟机里注册一个关闭钩子,这样就可保证Spring容器被恰当关闭,且自动执行singleton Bean实例的析构回调方法。

为了注册关闭钩子,只需要调用在AbstractApplicationContext中提供的registerShutdownHook( )方法即可。

从程序的输出可以看出:Spring容器注入之后,关闭之前,程序先调用destroy方法进行回收资源,再调用close方法进行回收资源。

如果某个Bean类实现了DisposableBean接口,在Bean被销毁之前,Spring容器会自动调用该Bean实例的destroy方法,其结果与采用destroy-method属性指定生命周期方法几乎一样。但实现DisposableBean接口污染了代码,是侵入式设计,因此不推荐使用。

除此之外,如果容器中很多Bean都需要指定特定的生命周期行为,则可以利用 <beans.../> 元素的 default-init-method属性和 default-destroy-method 属性,这两个属性的作用类似于 <bean.../>元素的 init-method 属性和destroy-method 属性,区别是default-init-method和default-destroy-method是针对容器中所有Bean生效。

需要指出的是,当Bean实现了ApplicationContextAware接口、BeanNameAware接口之后,Spring容器会在该Bean初始化完成之后,也就是调用init-method属性指定的方法之后,再来回调setApplicationContext(ApplicationContext appCtx)、setBeanName(String name)方法。



评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值