问题: 同一个类中的方法互相调用,被调用方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
}
}
网友评论