关于spring:Spring-aop-通过获取代理对象实现事务切换

34次阅读

共计 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. 留神点

  1. AopContext.currentProxy() 的实质是应用的 ThreadLocal 生成本地代理,这样的做法可能影响性能。
  2. 被代理对象应用的办法必须是 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 触发胜利!!!";}
}

正文完
 0