读书人

Spring署理的限制

发布时间: 2012-10-09 10:21:45 作者: rapoo

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都是无法感知的

读书人网 >编程

热点推荐