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");
}
}

运行Main程序,打印如下结果:

ceshi InitializingBean

这说明在spring初始化bean的时候,如果bean实现了InitializingBean接口,会自动调用afterPropertiesSet方法。

问题

实现InitializingBean接口与在配置文件中指定init-method有什么不同?

修改配置文件,加上init-method配置,修改如下:

<bean id="testInitializingBean" class="com.TestInitializingBean" init-method="testInit"></bean>

在配置文件中加入init-method="testInit"。

运行Main程序,打印如下结果:

ceshi InitializingBean
ceshi init-method

由结果可看出,在spring初始化bean的时候,如果该bean是实现了InitializingBean接口,并且同时在配置文件中指定了init-method,系统则是先调用afterPropertiesSet方法,然后在调用init-method中指定的方法。

这方式在spring中是怎么实现的?

通过查看spring的加载bean的源码类(AbstractAutowireCapableBeanFactory)可看出其中奥妙

AbstractAutowireCapableBeanFactory类中的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接口使用理解的更多相关文章

  1. spring中InitializingBean接口使用理解(转)

    InitializingBean接口为bean提供了初始化方法的方式,它只包括afterPropertiesSet方法,凡是继承该接口的类,在初始化bean的时候会执行该方法. 测试程序如下: imp ...

  2. spring 中 InitializingBean 接口使用理解

    前言:这两天在看 spring 与 quart 的集成,所以了解到 spring 是如何初始化 org.springframework.scheduling.quartz.SchedulerFacto ...

  3. spring中ApplicationContextAware接口使用理解

    一.这个接口有什么用?当一个类实现了这个接口(ApplicationContextAware)之后,这个类就可以方便获得ApplicationContext中的所有bean.换句话说,就是这个类可以直 ...

  4. 转:spring中InitailizingBean接口的简单理解

    转自:https://www.cnblogs.com/wxgblogs/p/6849782.html spring中InitializingBean接口使用理解   InitializingBean接 ...

  5. Spring中Ordered接口简介

    目录 前言 Ordered接口介绍 Ordered接口在Spring中的使用 总结 前言 Spring中提供了一个Ordered接口.Ordered接口,顾名思义,就是用来排序的. Spring是一个 ...

  6. spring中ApplicationContextAware接口描述

    项目中使用了大量的工厂类,采用了简单工厂模式: 通过该工厂类可以获取指定的处理器bean,这些处理器bean我们是从spring容器中获取的,如何获取,是通过实现ApplicationContextA ...

  7. 【spring】InitializingBean接口

    apollo 源码中有这么一个类 public class ReleaseMessageScanner implements InitializingBean @Override public voi ...

  8. spring(五):spring中Aware接口的使用

    spring中自定义组件需要使用spring的底层组件时,可以通过自定义组件实现相关XxxAware接口,重写其中的方法进而实现 例如:自定义一个组件,该组件中需要使用ApplicationConte ...

  9. spring中scope(作用越)理解

    今天总结了一下spring中作用域scope的用法.在spring中作用域通过配置文件形式的用法如下. <bean id="role" class="spring. ...

随机推荐

  1. [Network Analysis] 复杂网络分析总结

    在我们的现实生活中,许多复杂系统都可以建模成一种复杂网络进行分析,比如常见的电力网络.航空网络.交通网络.计算机网络以及社交网络等等.复杂网络不仅是一种数据的表现形式,它同样也是一种科学研究的手段.复 ...

  2. SQL Server数据库设计规范

    数据库设计规范 1.简介 数据库设计是指对一个给定的应用环境,构造最优的数据库模式,建立数据库及其他应用系统,使之能有效地存储数据,满足各种用户的需求.数据库设计过程中命名规范很是重要,命名规范合理的 ...

  3. 如何理解 卷积 和pooling

    转自:http://blog.csdn.net/malefactor/article/details/51078135 CNN是目前自然语言处理中和RNN并驾齐驱的两种最常见的深度学习模型.图1展示了 ...

  4. C#计算代码执行时间

    System.Diagnostics.Stopwatch watch = new Stopwatch();watch.Start(); //要计算的操作 DoSomeThing(); watch.St ...

  5. ios app 企业帐号发布,在浏览器中直接点击链接下载安装

    软件环境:Xcode 6.4 参考链接: 1.http://zxs19861202.iteye.com/blog/1997722 2.http://www.cnblogs.com/abl1992/p/ ...

  6. 关于List的ConcurrentModificationException

    对ArrayList的操作我们可以通过索引象来访问,也可以通过Iterator来访问,只要不对ArrayList结构上进行修改都不会造成ConcurrentModificationException, ...

  7. 高通vuforia+Unity3D 制作ar app

    很简单就可以用Unity3D做出增强现实的一个小例子 新人第一次写博客,若出现错误望指正^_^ 需要下载de东西: unity3d 5.0 http://unity3d.com/get-unity   ...

  8. 史上最详细的linux网卡ifcfg-eth0配置详解

    通过查资料与工作中的进行一下总结: DEVICE="eth1"   网卡名称NM_CONTROLLED="yes"      network mamager的参 ...

  9. Zabbix Trapper items

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px STHeiti; color: #313131 } span.s1 { } 概述 Trappe ...

  10. VirtualBox安装MS-DOS6.22(图文教程)

    最近在读一些计算机发展史之类的文献,总感觉的纸上得来终觉浅,所以打算自己装一个MS-DOS,体验一下远古的操作系统!可以google到MS-DOS的安装文件: 为什么要分成三个呢?可以看到,每个大小都 ...