Spring 扩展点系列:
首先,什么是 Spring 的扩展点呢?IOC 容器对 bean 的管理从 BeanDefinition 的注册到实例化再到依赖注入,有自己一套默认的流程,而 Spring 预留的扩展点允许某些 bean 干预这个预设的流程。
下面来看一个例子:

那问题来了,什么样的码农会选择去加班(什么样的 bean 会用到扩展点)?那还用说,肯定是想拿或者已经拿了更多薪水的人啊,公司会它们做更多的事情。同理,当某个 bean 实现了 Spring 中预置的扩展接口,比如 FactoryBean,InitialingBean 等接口,它就有了更大的能力,所以 IOC 容器对 bean 处理的流程就需要它来干预。
所以本篇我们就来看看 Spring 中有哪些常用的扩展点(接口)…
InitializingBean、DisposableBean
这两个接口是功能类似,所以放在一起:
- InitializingBean 接口中只有一个方法 afterPropertiesSet()。实现 InitialingBean 的 bean,可以在 bean 属性都设置完毕后调用 afterPropertiesSet() 方法做一些初始化的工作。
- DisposableBean 接口也只有一个方法 destory()。实现 DisposableBean 接口的 bean,可以在 bean生命周期结束前调用 destory() 方法做一些收尾工作。
public interface InitializingBean {
void afterPropertiesSet() throws Exception;
}
public interface DisposableBean {
void destroy() throws Exception;
}
下面来看一个示例…
1)创建一个 bean 并实现 InitializingBean 和 DisposableBean
public class TestBean01 implements InitializingBean, DisposableBean {
// 设置一个成员变量
// 目的是为了观察 bean 通过 setter 进行初始化
private String name;
public void setName(String name) {
this.name = name;
System.out.println("setName()..."+name);
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("afterPropertiesSet()...");
}
// 模拟 bean 的一些逻辑
public void doSomeWork() {
System.out.println("doSomeWork()...");
}
@Override
public void destroy() throws Exception {
System.out.println("destory()...");
}
}
2)配置一个 applicationContext.xml,将上面的 bean01 配置进 IOC 容器:
<?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-4.1.xsd">
<bean id="bean01" class="com.xupt.yzh.pkg_04.TestBean01">
<property name="name" value="张三" />
</bean>
</beans>
3)测试代码:
public class Main {
public static void main(String[] args) {
// 在初始化 IOC 容器时创建bean实例时就会调用 afterPropertiesSet()
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
// 模拟对 bean 进行一些操作
TestBean01 bean01 = (TestBean01)context.getBean("bean01");
bean01.doSomeWork();
// 必须要手动调用close方法,IOC容器才会去销毁那些存在的bean,才会调用 destroy()
context.close();
}
}
=> 结果如下:
可以看到 afterPropertiesSet() 方法就如同它的名字所表示的那样,是在 Bean 的属性都被设置完毕之后才会调用;而 destory() 方法是在手动调用 close() 关闭 IOC 容器后才会调用。
afterPropertiesSet() 方法是在 bean 的属性设置之后才会进行调用,某个 bean 的 afterPropertiesSet() 方法执行完毕才会执行下一个 bean 的 afterPropertiesSet() 方法,因此不建议在 afterPropertiesSet() 方法中写处理时间太长的方法。
另外,这里再说一下 init-method、destory-method
- InitializingBean接口、Disposable接口可以和 init-method、destory-method 配合使用,接口执行顺序优先于配置
- InitializingBean接口、Disposable接口底层使用类型强转.方法名()进行直接方法调用,init-method、destory-method底层使用反射,前者和Spring耦合程度更高但效率高,后者解除了和Spring之间的耦合但是效率低,使用哪个看个人喜好







还没有评论,来说两句吧...