简介
这两个接口是一组的,功能类似,因此放在一起:前者顾名思义在Bean属性都设置完毕后调用afterPropertiesSet()方法做一些初始化的工作,后者在Bean生命周期结束前调用destory()方法做一些收尾工作。下面看一下例子,为了能明确地知道afterPropertiesSet()方法的调用时机,加上一个属性,给属性set方法,在set方法中打印一些内容:
自定义bean 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 package com.fuyi.test; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; public class Foobar implements InitializingBean, DisposableBean{ @SuppressWarnings("unused") private String name; public void setName(String name) { this.name = name; System.out.println("进入setter方法中"); } //该bean中的属性都set完后调用,即setter方法调用完执行 @Override public void afterPropertiesSet() throws Exception { System.out.println("进入afterPropertiesSet方法"); } //在bean的生命周期结束前,调用该方法做一些收尾工作 @Override public void destroy() throws Exception { System.out.println("进入destroy方法"); } //业务方法 public String sayHello() { return "I am " + name; } }
配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" 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-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd"> <bean id="foobar" class="com.fuyi.test.Foobar"> <property name="name" value="fuyi"></property> </bean> </beans>
启动Spring容器测试 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 @Test public void testInitialingBean(){ AbstractApplicationContext ac = new ClassPathXmlApplicationContext("classpath:bean.xml"); Foobar foobar = (Foobar) ac.getBean("foobar"); //基于web的ApplicationContext会自动在web应用关闭时,自动关闭IOC容器 //非web时,可以在JVM中注册一个“关闭钩子”,确保IOC容器被恰当关闭,单例bean持有的资源被释放,回调destory()方法 ac.registerShutdownHook(); ac.start(); String sayHello = foobar.sayHello(); System.out.println(sayHello); } //执行的结果为: 进入setter方法中 进入afterPropertiesSet方法 I am fuyi 进入destroy方法
关于这两个接口,我总结几点:
InitializingBean接口、Disposable接口可以和init-method、destory-method配合使用,接口执行顺序优先于配置
InitializingBean接口、Disposable接口底层使用类型强转.方法名()进行直接方法调用,init-method、destory-method底层使用反射,前者和Spring耦合程度更高但效率高,后者解除了和Spring之间的耦合但是效率低,使用哪个看个人喜好
afterPropertiesSet()方法是在Bean的属性设置之后才会进行调用,某个Bean的afterPropertiesSet()方法执行完毕才会执行下一个Bean的afterPropertiesSet()方法,因此不建议在afterPropertiesSet()方法中写处理时间太长的方法