关于在Spring容器初始化和销毁Bean前所做的操作定义方式有三种,分别是注解、XML文件和实现指定接口三种方式来初始化和销毁Bean。
Spring提供了两个注解供我们来使用,分别是@PostConstruct和@PreDestroy方法, 前者指定初始化方法,后者指定销毁方法。实例程序如下:
package ioc.initDestroy; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; /** * 用来测试Spring对Bean的初始化和销毁方式 * @author huangxin * @date 2016年4月25日23:06:59 */ public class InitBean02 { private static final String NAME = InitBean02.class.getName(); /** * 初始化方法 */ @PostConstruct public void init() { System.out.println(NAME + " :: init()"); } /** * 销毁方法 */ @PreDestroy public void destroy() { System.out.println(NAME + " :: destroy()"); } /** * 业务方法 */ public void businessMethod() { System.out.println(NAME + " :: businessMethod()"); } }
在使用注解方式来指定初始化和销毁方法时,需要我们的JDK是1.5版本以上,才能支持原生注解的功能。并且我们需要在Spring中启用注解的功能,通过如下简单的代码既可启动注解,如下:
<context:annotation-config />
注意:使用该方法的时候我们还需要引入context命名空间和XSD(模式文件)文件。
完整的Spring配置信息如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="https://www.springframework.org/schema/beans" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns:context="https://www.springframework.org/schema/context" xsi:schemaLocation="https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans-3.2.xsd https://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context-3.2.xsd" default-lazy-init="true" default-autowire="byName"> <context:annotation-config /> <bean id="initBean02" class="ioc.initDestroy.InitBean02" /> </beans>
这种方式是最简单和容易理解的方式,Spring在bean定义标签中提供了init-method和destory-method两个属性,前者指定bean的初始方法,后者指定bean的销毁方法。实例代码如下:
package ioc.initDestroy; /** * 用来测试Spring对Bean的初始化和销毁方式 * @author huangxin * @date 2016年4月25日23:06:59 */ public class InitBean01 { private static final String NAME = InitBean01.class.getName(); /** * 初始化方法 */ public void init() { System.out.println(NAME + " :: init()"); } /** * 销毁方法 */ public void destroy() { System.out.println(NAME + " :: destroy()"); } /** * 业务方法 */ public void businessMethod() { System.out.println(NAME + " :: businessMethod()"); } }
下面是Spring完整的配置文件:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="https://www.springframework.org/schema/beans" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans-3.2.xsd" default-lazy-init="true" default-autowire="byName"> <bean id="initBean01" class="ioc.initDestroy.InitBean01" init-method="init" destroy-method="destroy" /> </beans>
这是不推荐使用的方式,因为造成了Spring API对业务代码的侵入性。这种方式需要自己去实现Spring提供的接口InitializingBean(初始化)和接口DisposableBean(销毁)。实例代码如下:
package ioc.initDestroy; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; /** * 用来测试Spring对Bean的初始化和销毁方式 * @author huangxin * @date 2016年4月25日23:06:59 */ public class InitBean03 implements InitializingBean, DisposableBean { private static final String NAME = InitBean03.class.getName(); /** * 初始化方法 */ @Override public void afterPropertiesSet() throws Exception { System.out.println(NAME + " :: afterPropertiesSet()"); } /** * 销毁方法 */ @Override public void destroy() throws Exception { System.out.println(NAME + " :: destroy()"); } /** * 业务方法 */ public void businessMethod() { System.out.println(NAME + " :: businessMethod()"); } }
下面是Spring的配置文件:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="https://www.springframework.org/schema/beans" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans-3.2.xsd" default-lazy-init="true" default-autowire="byName"> <bean id="initBean03" class="ioc.initDestroy.InitBean03" /> </beans>
下面提供了调用上面几种方式的java代码,自己运行观察结果:
package ioc.initDestroy; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * 测试Spring Bean初始化和销毁 * @author huangxin * @date 2016年4月25日22:59:57 */ public class InitDestroyClient { private AbstractApplicationContext context; public InitDestroyClient() { // 加载Spring配置文件 String xmlPath = "ioc/initDestroy/applicationContext.xml"; context = new ClassPathXmlApplicationContext(xmlPath); InitBean01 initBean01 = context.getBean(InitBean01.class); initBean01.businessMethod(); InitBean02 initBean02 = context.getBean(InitBean02.class); initBean02.businessMethod(); InitBean03 initBean03 = context.getBean(InitBean03.class); initBean03.businessMethod(); // 关闭Spring容器 context.registerShutdownHook(); } public static void main(String[] args) { new InitDestroyClient(); } }
registerShutdownHook()是一个钩子方法(在AbstractApplicationContext类中定义),当jvm关闭退出的时候会调用这个钩子方法,在设计模式之模板模式中通过在抽象类中定义这样的钩子方法由实现类进行实现,这里的实现类是AbstractApplicationContext,这是Spring 容器优雅关闭的方法。