Spring署理的限制

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.
		 */
		@Override
		protected 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都是无法感知的