共计 1263 个字符,预计需要花费 4 分钟才能阅读完成。
Spring aop 通过获取代理对象实现事务切换
在我的项目中,波及到同一个类中一个办法调用另外一个办法,并且两个办法的事务不相干。
这外面波及到一个事务切换的问题,通过 spring aop 类外面的 AopContext 类获取以后类的代理对象,这样就能切换对应的事务管理器了,具体做法如下:
1. 配置
1.1 在 applicationContext.xml 文件中配置如下:
<!-- 开启裸露 Aop 代理到 ThreadLocal 反对 -->
<aop:aspectj-autoproxy expose-proxy="true"/>
1.2 在所在类或者启动类上配置 @EnableAspectJAutoProxy 注解
@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
2. 应用办法
在须要切换的中央获取代理对象,再调用对应的办法,如下:
((类名) AopContext.currentProxy()). 办法 ();
3. 留神点
- AopContext.currentProxy() 的实质是应用的 ThreadLocal 生成本地代理,这样的做法可能影响性能。
-
被代理对象应用的办法必须是 public 类型的办法,不然获取不到代理对象,会报上面的谬误:
java.lang.IllegalStateException: Cannot find current proxy: Set 'exposeProxy' property on Advised to 'true' to make it available.
开启裸露 AOP 代理即可。
因为开启事务和事务回滚,理论这个过程是 aop 代理帮忙实现的,当调用一个办法时,它会先查看时候有事务,有则开启事务。
当调用本类的办法时,它并没有将其视为 proxy 调用,而是办法的间接调用,所以也就没有查看该办法是否含有事务这个过程,
那么本地办法调用的事务也就有效了。
4. demo
@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
public class TransactionTest {
/**
* 办法 A 没事务
*
* @param
* @return void
*/
public String A(){System.out.println("A 办法执行开始!!!");
// 生成 TransactionTest 代理类,再调用 B 办法,B 的事务就回独自失效,并且异样回滚
String result = ((TransactionTest)AopContext.currentProxy()).B();
System.out.println("A 办法执行完结!!!");
return result;
}
/**
* 事务 B 独自的事务
* 应用代理,同一类中 A 办法调用 B 办法事务能够失效
* @param
* @return void
*/
@Transactional(rollbackFor = Exception.class)
public String B(){return "事务 B 触发胜利!!!";}
}
正文完