美文网首页Spring专题
Spring专题: 4. AOP失效的场景与原理

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

作者: 北交吴志炜 | 来源:发表于2019-01-04 19: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
    
        }
    }
    

    相关文章

      网友评论

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

        本文链接:https://www.haomeiwen.com/subject/ymskrqtx.html