spring InitializingBean接口
TransactionTemplate的源码如下:
public class TransactionTemplate extends DefaultTransactionDefinition
implements TransactionOperations, InitializingBean{
.
.
.
}
TransactionTemplate继承了DefaultTransactionDefinition,实现了TransactionOperations,InitializingBean接口。先研究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");
}
}
配置文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="testInitializingBean" class="com.TestInitializingBean" ></bean>
</beans>
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配置,修改如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="testInitializingBean" class="com.TestInitializingBean" init-method="testInit"></bean>
</beans>
在配置文件中加入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指定的方法。
4:TransactionTemplate实现InitializingBean接口,主要是判断transactionManager是否已经初始化,如果没有则抛出异常。源码如下:
public void afterPropertiesSet() {
if (this.transactionManager == null) {
throw new IllegalArgumentException("Property 'transactionManager' is required");
}
}
来自:http://blog.csdn.net/mqboss/article/details/7452331
spring InitializingBean接口相关推荐
- Spring中的InitializingBean接口的使用
InitializingBean接口为bean提供了初始化方法的方式,它只包括afterPropertiesSet方法,凡是继承该接口的类,在初始化bean的时候会执行该方法,具体说spring初始化 ...
- Spring中的InitializingBean接口
InitializingBean接口为bean提供了初始化方法的方式,它只包括afterPropertiesSet方法,凡是继承该接口的类,在初始化bean的时候都会执行该方法. package o ...
- spring InitializingBean接口分析
最近工作需要得到sping中的每个事物需要执行的sql,称机会简单研究了一下spring的事务,项目中管理事务比较简单,用TransactionTemplate,就直接以TransactionTemp ...
- springbean的生命周期_spring bean生命周期(涵盖spring常用接口的载入)
spring bean生命周期流程图: 其中包含了很多常用的接口,可以参考spring 常用接口: 下面写个例子证明下: 1.实现InitializingBean以及各个Aware接口 p ...
- 换一种方式编写 Spring MVC 接口
点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 1. 前言 通常我们编写 Spring MVC 接口的范 ...
- InitializingBean接口使用方法
1.定义 InitializingBean接口为bean提供了初始化方法的方式,它只包括afterPropertiesSet方法,凡是继承该接口的类,在初始化bean的时候都会执行该方法. 2.使用方 ...
- springcloud工作笔记104---Spring中的InitializingBean接口以及afterPropertiesSet的使用
技术交流QQ群[JAVA,C++,Python,.NET,BigData,AI]:170933152 这里为什么要说这个方法,因为我们物联网项目中,在做语音通信服务器的过程中,首先,由于 硬件设备发给 ...
- 护网必备技能:Spring Boot 接口数据加解密 功能实现
护网必备技能:Spring Boot 接口数据加解密 功能实现 文章目录 护网必备技能:Spring Boot 接口数据加解密 功能实现 1. 尽量少改动,不影响之前的业务逻辑: 2. 考虑到时间紧迫 ...
- Spring Boot 接口参数自动加解密
本文标题:Spring Boot 接口参数自动加解密 原始链接: https://www.shuibo.cn/102.html 许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链 ...
最新文章
- 刚刚,DeepMind被IJCAI授予杰出成就奖,因为他家把AlphaGo Zero做成了暖心的新垣结衣?
- 如何将mysql数据导入Hadoop之Sqoop安装
- SQLServer2000同步复制技术实现步骤
- 【分解质因数】【树状数组】【快速幂】codeforces 2014 ACM-ICPC Vietnam National Second Round E. ACM...
- U3D的结构体堆分配栈分配
- VTK:绘图之HistogramBarChart
- (Spinner) android中Spinner的使用
- USACO 2.1 海明码 Hamming Codes (模拟+位运算+黑科技__builtin_popcount(n))
- linux中的信号3——alarm、pause函数
- Linux系统下软件包管理六
- 数据结构学习笔记之一 链表
- wpf checkbox选中触发事件_Web前端开发(16)——JQuery事件绑定与插件
- java中用单例模式有什么好处
- A Beginner's Guide To Understanding Convolutional Neural Networks Part One (CNN)笔记
- java 整型 二进制_Java中如何得到一个整型数的二进制形式(十进制转化成二进制)...
- [Linux源码分析]Linux内核架构
- C语言将数组进行排序
- H264BSAnalyzer 使用方法
- LowB三人组--选择排序原理和实现
- H3C交换机设备常用命令
热门文章
- VTK:网格之WindowedSincPolyDataFilter
- OpenCV编写视频文件的实例(附完整代码)
- OpenCV使用蒙版mask过滤图像的实例(附完整代码)
- QT的QBoxLayout类的使用
- 经典C语言程序100例之七七
- dbms_java_java实现DBMS
- pcb 布线电容 影响延时_信号在PCB走线中传输时延
- php redis zset 延迟队列_PHP + Redis 实现简单消息队列
- 1.18.2.10 解释表:Table.explain、物理执行计划等
- B02_NumPy数据属性(ndarray.ndim,ndarray.shape,ndarray.itemsize,ndarray.flags)