Spring代理的限制
Spring的AOP的限制:
? ? ? ?aop无法拦截方法内部的调用,假如有方法
?
public class AccountServiceImpl implements AccoutService{ @Transactional public void increment(Account account, int amount){ doXXX(); } @Transactional public void decrement(Account account, int amount) { doXXX(); } public void transform(Account from,Account to,int amout){ decrement(from,amount); increment(to,amount); }}???transform方法内部的decrement();increment()虽然有Transactional,但是事物拦截器不会拦截到这两个方法调用
?
? cglib则可以解决此类问题,cglib的代理可以通过字节码增强,生成代理类型的子类型,并创建对象。
但,在spring中不论你用cglib,还是jdk动态代理都会存在上述问题。
? 根本原因是spring的代理是基于目标对象的代理而不是像cglib一样直接生成目标类型的子类型,像静态代理一样对目标对象的方法调用做一层包裹,并不管目标对象方法的内部调用。
看看Spring的
private static class CglibMethodInvocation extends ReflectiveMethodInvocation {private final MethodProxy methodProxy;private boolean protectedMethod;public CglibMethodInvocation(Object proxy, Object target, Method method, Object[] arguments,Class targetClass, List<Object> interceptorsAndDynamicMethodMatchers, MethodProxy methodProxy) {super(proxy, target, method, arguments, targetClass, interceptorsAndDynamicMethodMatchers);this.methodProxy = methodProxy;this.protectedMethod = Modifier.isProtected(method.getModifiers());}/** * Gives a marginal performance improvement versus using reflection to * invoke the target when invoking public methods. */@Overrideprotected Object invokeJoinpoint() throws Throwable {if (this.protectedMethod) {return super.invokeJoinpoint();}else {return this.methodProxy.invoke(this.target, this.arguments);}}}?看到其中的return this.methodProxy.invoke(this.target, this.arguments); 在target目标上直接做invoke,所以不论methodProxy内部有什么方法调用
spring都是无法感知的