Spring专题

Spring专题: 4. AOP失效的场景与原理

2019-01-04  本文已影响0人  北交吴志炜

问题: 同一个类中的方法互相调用,被调用方aop失效,比如下列代码,serviceA中调了serviceB,此时,加在serviceB上的事务注解(基于AOP)会失效

@Service
public class AServiceImpl implements AService {
    @Transactional
    public void serviceA() {
        System.out.println("serviceA");
        //db
        serviceB();

    }

    @Transactional
    public void serviceB() {
        System.out.println("serviceB");
        //db

    }
}

原理:
spring事务依赖的是SpringAop 动态代理,执行原理见之前的文章
无论是cglib,还是jdk代理,增强逻辑执行到最后,执行目标方法代码如下,此时,代码里面的target为目标对象,不是代理对象,嵌套方法中的内层方法是用目标对象直接调用的,没有经过aop代理对象。所以失效。

ReflectiveMethodInvocation.proceed();

public static Object invokeJoinpointUsingReflection(@Nullable Object target, Method method, Object[] args)
            throws Throwable {

        // Use reflection to invoke the method.
        try {
            ReflectionUtils.makeAccessible(method);
            return method.invoke(target, args);
        }

解决方案:
1.不要嵌套调用,将需要一个类中嵌套调用的方法,移到另一个类中
2.使用expose-proxy ,在代码中使用AopContext获取到代理对象,使用代理对象进行嵌套调用。

    <aop:aspectj-autoproxy expose-proxy="true"/>

强制用代理对象进行嵌套调用

@Service
public class AServiceImpl implements AService {
    @Transactional
    public void serviceA() {
        System.out.println("serviceA");
        //db
        AService proxy=(AService) AopContext.currentProxy();
        proxy.serviceB();

    }

    @Transactional
    public void serviceB() {
        System.out.println("serviceB");
        //db

    }
}
上一篇 下一篇

猜你喜欢

热点阅读