Spring中的InitializingBean接口的使用
InitializingBean接口为bean提供了初始化方法的方式,它只包括afterPropertiesSet方法,凡是继承该接口的类,在初始化bean的时候都会执行该方法。
测试,如下:
import org.springframework.beans.factory.InitializingBean;
public class TestInitializingBean implements InitializingBean{
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("ceshi InitializingBean");
}
public void testInit(){
System.out.println("ceshi init-method");
}
}
配置文件
<bean id="testInitializingBean" class="com.TestInitializingBean" ></bean>
Main函数如下
public class Main {
public static void main(String[] args){
ApplicationContext context = new FileSystemXmlApplicationContext("/src/main/java/com/beans.xml");
}
}
测试结果为:
ceshi InitializingBean
这说明在spring初始化bean的时候,如果bean实现了InitializingBean接口,会自动调用afterPropertiesSet方法。
那么问题来了,在配置bean的时候使用init-method配置也可以为bean配置初始化方法,那这两个哪个会先执行呢,接下来测试一下,修改配置文件,加上init-method:
<bean id="testInitializingBean" class="com.TestInitializingBean" init-method="testInit"></bean>
运行程序,得出结果:
ceshi InitializingBean
ceshi init-method
从结果可以看出,在Spring初始化bean的时候,如果该bean实现了InitializingBean接口,并且同时在配置文件中指定了init-method,系统则是先调用afterPropertieSet()方法,然后再调用init-method中指定的方法。
那么这种方式在spring中是怎么实现的呢,通过查看Spring加载bean的源码类AbstractAutowiredCapableBeanFactory可以看出其中的奥妙,AbstractAutowiredCapableBeanFactory类中的invokeInitMethods说的非常清楚,如下:
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd) throws Throwable {
//判断该bean是否实现了实现了InitializingBean接口,如果实现了InitializingBean接口,则只掉调用bean的afterPropertiesSet方法
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isDebugEnabled()) {
logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
public Object run() throws Exception {
//直接调用afterPropertiesSet
((InitializingBean) bean).afterPropertiesSet();
return null;
}
},getAccessControlContext());
} catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
//直接调用afterPropertiesSet
((InitializingBean) bean).afterPropertiesSet();
}
}
if (mbd != null) {
String initMethodName = mbd.getInitMethodName();
//判断是否指定了init-method方法,如果指定了init-method方法,则再调用制定的init-method
if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
//进一步查看该方法的源码,可以发现init-method方法中指定的方法是通过反射实现
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
总结:
1、Spring为bean提供了两种初始化bean的方式,实现InitializingBean接口,实现afterPropertiesSet方法,或者在配置文件中通过init-method指定,两种方式可以同时使用。
2、实现InitializingBean接口是直接调用afterPropertiesSet方法,比通过反射调用init-method指定的方法效率要高一点,但是init-method方式消除了对spring的依赖。
3、如果调用afterPropertiesSet方法时出错,则不调用init-method指定的方法。
Spring中的InitializingBean接口的使用的更多相关文章
- Spring中的InitializingBean接口
InitializingBean接口为bean提供了初始化方法的方式,它只有afterPropertiesSet方法,凡是继承该接口的类,在初始化bean的时候会执行该方法. 测试程序如下: impo ...
- spring中基础核心接口总结
spring中基础核心接口总结理解这几个接口,及其实现类就可以快速了解spring,具体的用法参考其他spring资料 1.BeanFactory最基础最核心的接口重要的实现类有:XmlBeanFac ...
- Spring中的InitializingBean与DisposableBean
InitializingBean顾名思义,应该是初始化Bean相关的接口. 先看一下该接口都定义了哪些方法: public interface InitializingBean { void afte ...
- Spring中Aware相关接口原理
Spring中提供一些Aware相关接口,像是BeanFactoryAware. ApplicationContextAware.ResourceLoaderAware.ServletContextA ...
- spring中的aware接口
1.实现了相应的aware接口,这个类就获取了相应的资源. 2.spring中有很多aware接口,包括applicationContextAware接口,和BeanNameAware接口. 实现了这 ...
- spring中一些aware接口
Spring中提供一些Aware相关接口,像是BeanFactoryAware. ApplicationContextAware.ResourceLoaderAware.ServletContextA ...
- 谈谈Spring中的BeanPostProcessor接口
一.前言 这几天正在复习Spring的相关内容,在了解bean的生命周期的时候,发现其中涉及到一个特殊的接口--BeanPostProcessor接口.由于网上没有找到比较好的博客,所有最后花了好 ...
- Spring 中的 MetaData 接口
什么是元数据(MetaData) 先直接贴一个英文解释: Metadata is simply data about data. It means it is a description and co ...
- MyBatis-Spring中间件逻辑分析(怎么把Mapper接口注册到Spring中)
1. 文档介绍 1.1. 为什么要写这个文档 接触Spring和MyBatis也挺久的了,但是一直还停留在使用的层面上,导致很多时候光知道怎么用,而不知道其具体原理,这样就很难做一 ...
随机推荐
- $(function(){})和window.onload的区别
(1)$(function(){}):DOM节点创建 完成才执行 (2)window.onload:页面所有资源(JS/CSS)加载完成才执行
- C++ 异常小记
catch必定使用拷贝构造函数 如下代码编译不通过,因为拷贝构造被标记delete #include <stdexcept> #include <cstdlib> #inclu ...
- JavaScript查找数组中最大的值
// 查找一个数组中最大的数 // 定义一个方法 searchMax function searchMax(arr) { // 声明一个变量MaxNumber假设为数组中最大的值arr[0]; var ...
- java对象转字节数组,获取泛型类
对象转字节数组,字节数组在恢复成对象 Test.java class Test { public static void main(String args[]) throws IOException, ...
- Python内置函数(63)——property
英文文档: class property(fget=None, fset=None, fdel=None, doc=None) Return a property attribute. fget is ...
- Python-迭代器&生成器&装饰器&软件目录结构规范-Day5
目录Day-Python-迭代器&生成器 21.生成器 21.1.生成器引入 21.2.生成器作用 31.3.创建生成器的方法 31.4.用函数来实现复杂的生成器 51.5.把函数变成生成器通 ...
- unity A*寻路 (三)A*算法
这里我就不解释A*算法 如果你还不知道A*算法 网上有很多简单易懂的例子 我发几个我看过的链接 http://www.cnblogs.com/lipan/archive/2010/07/01/1769 ...
- Apollo单向SSL认证(1)
参考链接:https://www.cnblogs.com/benwu/articles/4891758.html keytool -genkey -alias mybroker -keyalg RSA ...
- python中两种方法实现二分法查找,细致分析二分法查找算法
之前分析了好多排序算法,可难理解了呢!!(泣不成声)这次我要把二分查找总结一下,这个算法不算难度特别大,欢迎大家参考借鉴我不喜欢太官方的定义,太晦涩的语言,让人看了就头晕.我希望加入我自己的理解,能帮 ...
- 南京邮电大学java程序设计作业在线编程第四次作业
王利国的的 "Java语言程序设计第4次作业(2018)" 详细 主页 我的作业列表 作业结果详细 总分:100 选择题得分:40 1.下列方法定义中,正确的是() A.doub ...