1
头图

Spring aop realizes transaction switching by obtaining proxy objects

In the project, one method in the same class is involved in calling another method, and the transactions of the two methods are not related.
This involves a transaction switching problem. The proxy object of the current class is obtained through the AopContext class in the spring aop class, so that the corresponding transaction manager can be switched. The specific methods are as follows:

1. Configuration

1.1 The configuration in the applicationContext.xml file is as follows:
<!-- 开启暴露Aop代理到ThreadLocal支持  -->  
<aop:aspectj-autoproxy expose-proxy="true"/>  
1.2 Configure the @EnableAspectJAutoProxy annotation on the class or startup class
@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true) 

2. How to use

Get the proxy object where you need to switch, and then call the corresponding method, as follows:

((类名) AopContext.currentProxy()).方法(); 

3. Points to note

  1. The essence of AopContext.currentProxy() is to use ThreadLocal to generate a local proxy, which may affect performance.
  2. The method used by the proxy object must be a public method, otherwise the proxy object cannot be obtained, and the following error will be reported:

    java.lang.IllegalStateException: Cannot find current proxy: Set 'exposeProxy' property on Advised to 'true' to make it available.

    Just open the exposed AOP proxy.
    Because the transaction is opened and the transaction is rolled back, the actual process is completed with the help of the aop agent. When a method is called, it will first check when there is a transaction, and if there is a transaction, it will start the transaction.
    When the method of this class is called, it does not regard it as a proxy call, but a direct call of the method, so it does not check whether the method contains the transaction process.
    Then the transaction of the local method call is invalid.

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触发成功!!!";
    }
}

莫小点还有救
219 声望26 粉丝

优秀是一种习惯!