Spring事务管理机制的实现原理-动态代理
之前在做项目中遇到spring无法进行事务代理问题,最后发现是因为没有写接口,原因当时明白了,看到这篇文章写的清楚些,转过来
我们先来分析一下Spring事务管理机制的实现原理。由于Spring内置AOP默认使用动态代理模式实现,我们就先来分析一下动态代理模式的实现方 法。动态代理模式的核心就在于代码中不出现与具体应用层相关联的接口或者类引用,如上所说,这个代理类适用于任何接口的实现。下面我们来看一个例子。
public class TxHandler implements InvocationHandler {
private Object originalObject;
public Object bind(Object obj) {
this.originalObject = obj;
return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),this);
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object result = null;
if (!method.getName().startsWith("save")) {
UserTransaction tx = null;
try {
tx = (UserTransaction) (new InitialContext().lookup("java/tx"));
result = method.invoke(originalObject, args);
tx.commit();
} catch (Exception ex) {
if (null != tx) {
try {
tx.rollback();
} catch (Exception e) {
}
}
}
} else {
result = method.invoke(originalObject, args);
}
return result;
}
}
下面我们来分析一下上述代码的关键所在。
首先来看一下这段代码:
return Proxy.newProxyInstance(
obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),this);
java.lang.reflect.Proxy.newProxyInstance方法根据传入的接口类型 (obj.getClass.getInterfaces())动态构造一个代理类实例返回,这也说明了为什么动态代理实现要求其所代理的对象一定要实现 一个接口。这个代理类实例在内存中是动态构造的,它实现了传入的接口列表中所包含的所有接口。
再来分析以下代码:
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
……
result = method.invoke(originalObject, args);
……
return result;
}
InvocationHandler.invoke方法将在被代理类的方法被调用之前触发。通过这个方法,我们可以在被代理类方法调用的前后进行一些处 理,如代码中所示,InvocationHandler.invoke方法的参数中传递了当前被调用的方法(Method),以及被调用方法的参数。同 时,可以通过method.invoke方法调用被代理类的原始方法实现。这样就可以在被代理类的方法调用前后写入任何想要进行的操作。
Spring的事务管理机制实现的原理,就是通过这样一个动态代理对所有需要事务管理的Bean进行加载,并根据配置在invoke方法中对当前调用的 方法名进行判定,并在method.invoke方法前后为其加上合适的事务管理代码,这样就实现了Spring式的事务管理。Spring中的AOP实 现更为复杂和灵活,不过基本原理是一致的。
Spring事务管理机制的实现原理-动态代理的更多相关文章
- spring 事务管理机制
1. spring 事务管理抽象 spring 的事务策略机制的核心就是 org.springframework.transaction.PlatformTransactionManager 接口. ...
- Spring入门5.事务管理机制
Spring入门5.事务管理机制 20131126 代码下载 : 链接: http://pan.baidu.com/s/1kYc6c 密码: 233t 回顾之前的知识,Spring 最为核心的两个部分 ...
- Spring 事务管理原理探究
此处先粘贴出Spring事务需要的配置内容: 1.Spring事务管理器的配置文件: 2.一个普通的JPA框架(此处是mybatis)的配置文件: <bean id="sqlSessi ...
- 《深入理解mybatis原理》 MyBatis事务管理机制
MyBatis作为Java语言的数据库框架,对数据库的事务管理是其很重要的一个方面.本文将讲述MyBatis的事务管理的实现机制. 首先介绍MyBatis的事务Transaction的接口设计以及其不 ...
- Spring入门6事务管理2 基于Annotation方式的声明式事务管理机制
Spring入门6事务管理2 基于Annotation方式的声明式事务管理机制 201311.27 代码下载 链接: http://pan.baidu.com/s/1kYc6c 密码: 233t 前言 ...
- Spring总结九:事务管理机制
何为事务 事务(Transaction),一般是指要做的或所做的事情.在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序执行单元(unit).事务通常由高级数据库操纵语言或编程语言(如SQL ...
- Spring 框架基础(05):事务管理机制,和实现方式
本文源码:GitHub·点这里 || GitEE·点这里 一.Spring事务管理 1.基础描述 Spring事务管理的本质就是封装了数据库对事务支持的操作,使用JDBC的事务管理机制,就是利用jav ...
- 【Java EE 学习 52】【Spring学习第四天】【Spring与JDBC】【JdbcTemplate创建的三种方式】【Spring事务管理】【事务中使用dbutils则回滚失败!!!??】
一.JDBC编程特点 静态代码+动态变量=JDBC编程. 静态代码:比如所有的数据库连接池 都实现了DataSource接口,都实现了Connection接口. 动态变量:用户名.密码.连接的数据库. ...
- [转]Spring3核心技术之事务管理机制
原文地址:http://chouyi.iteye.com/blog/1675199 Spring对事务的解决办法其实分为2种:编程式实现事务,AOP配置声明式解决方案. http://jinnians ...
随机推荐
- MFC 中GetClientRect、ClientToScreen、GetWindow、RectScreenToClient的使用
CWnd* pWnd = GetDlgItem(IDB_BUT_RECOGNIZE); pWnd->GetClientRect(&rect); //指该控件自身客户区的矩形,原点为控 ...
- 对FPGA的时钟资源理解(更新中)
7系列FPGA中包含了多达24个CMT(时钟管理单元)(实际上V7常见只有20个),MMCM和PLL均为时钟综合器,对外部输入时钟.内部时钟进行处理,生成需要的低抖动时钟.PLL是MMCM的功能子集, ...
- 201621123001 《Java程序设计》第10周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容. 2. 书面作业 本次PTA作业题集 异常 1. 常用异常 结合题集题目7-1回答 1.1 自己以前编写的代码中经常出 ...
- codeforce150A(简单的求质数问题)
A. Win or Freeze time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...
- L320 What late-night snacking has to do with sleep
What late-night snacking has to do with sleep Light-night snacking isn’t just something college stud ...
- L271 操纵太空中航天器的几种方法
Manoeuvring a satellite in orbit usually requires thrusters. Sometimes the thrust is provided by a f ...
- smali语法详解
smali文件格式 每个smali文件都由若干条语句组成,所有的语句都遵循着一套语法规则.在smali 文件的头3 行描述了当前类的一些信息,格式如下: .class < 访问权限> [ ...
- PAT乙级 1031. 查验身份证(15)
题目传送:https://www.patest.cn/contests/pat-b-practise/1031 一个合法的身份证号码由17位地区.日期编号和顺序编号加1位校验码组成.校验码的计算规则如 ...
- 【Python】进程间共享实例
#练习:进程间共享实例 import time,os import random from multiprocessing import Pool,Value,Lock,Manager from mu ...
- VS2017调试代码显示“当前无法命中断点,还没有为该文档加载任何符号”
VS2017升级之后,代码调试无法进入,显示“当前无法命中断点,还没有为该文档加载任何符号”的问题解决思路: 1.工具-选项-项目和解决方案-生成并运行,取消勾选“在运行时仅生成启动项目和依赖性” 2 ...