初探spring aop内部实现

 最近考到一篇3年前的文章,让我对spring的aop的内部实现有了更深刻的认识。

现转帖如下.原帖地址:http://www.javaeye.com/topic/39912

 

AOP功能强大,但是spring是如何来实现AOP技术的呢?
SPRING是通过动态代理来实现AOP的,SPRING内部提供了2种实现机制
1.如果是有接口声明的类进行AOP,spring调用的是java.lang.reflection.Proxy类来做处理

Java代码 复制代码
  1. org.springframework.aop.framework.JdkDynamicAopProxy   
  2.     public Object getProxy(ClassLoader classLoader) {   
  3.         if (logger.isDebugEnabled()) {   
  4.             Class targetClass = this.advised.getTargetSource().getTargetClass();   
  5.             logger.debug("Creating JDK dynamic proxy" +   
  6.                     (targetClass != null ? " for [" + targetClass.getName() + "]" : ""));   
  7.         }   
  8.         Class[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);   
  9.         return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);   
  10.     }   
  11.   
  12. org.springframework.aop.framework.ReflectiveMethodInvocation   
  13. public Object proceed() throws Throwable {   
  14.         //  We start with an index of -1 and increment early.   
  15.         if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {   
  16.             return invokeJoinpoint();   
  17.         }   
  18.   
  19.         Object interceptorOrInterceptionAdvice =   
  20.             this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);   
  21.         if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {   
  22.             // Evaluate dynamic method matcher here: static part will already have   
  23.             // been evaluated and found to match.   
  24.             InterceptorAndDynamicMethodMatcher dm =   
  25.                 (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;   
  26.             if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {   
  27.                 return dm.interceptor.invoke(this);   
  28.             }   
  29.             else {   
  30.                 // Dynamic matching failed.   
  31.                 // Skip this interceptor and invoke the next in the chain.   
  32.                 return proceed();   
  33.             }   
  34.         }   
  35.         else {   
  36.             // It's an interceptor, so we just invoke it: The pointcut will have   
  37.             // been evaluated statically before this object was constructed.   
  38.             return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);   
  39.         }   
  40.     }  
org.springframework.aop.framework.JdkDynamicAopProxy
	public Object getProxy(ClassLoader classLoader) {
		if (logger.isDebugEnabled()) {
			Class targetClass = this.advised.getTargetSource().getTargetClass();
			logger.debug("Creating JDK dynamic proxy" +
					(targetClass != null ? " for [" + targetClass.getName() + "]" : ""));
		}
		Class[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);
		return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
	}

org.springframework.aop.framework.ReflectiveMethodInvocation
public Object proceed() throws Throwable {
		//	We start with an index of -1 and increment early.
		if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
			return invokeJoinpoint();
		}

		Object interceptorOrInterceptionAdvice =
		    this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
		if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
			// Evaluate dynamic method matcher here: static part will already have
			// been evaluated and found to match.
			InterceptorAndDynamicMethodMatcher dm =
			    (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
			if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
				return dm.interceptor.invoke(this);
			}
			else {
				// Dynamic matching failed.
				// Skip this interceptor and invoke the next in the chain.
				return proceed();
			}
		}
		else {
			// It's an interceptor, so we just invoke it: The pointcut will have
			// been evaluated statically before this object was constructed.
			return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
		}
	}



2.如果是没有接口声明的类呢?SPRING通过CGLIB包和内部类来实现

Java代码 复制代码
  1. private static class StaticUnadvisedInterceptor implements MethodInterceptor, Serializable {   
  2.   
  3.         private final Object target;   
  4.   
  5.         public StaticUnadvisedInterceptor(Object target) {   
  6.             this.target = target;   
  7.         }   
  8.   
  9.         public Object intercept(Object proxy, Method method, Object[] args,   
  10.                 MethodProxy methodProxy) throws Throwable {   
  11.   
  12.             Object retVal = methodProxy.invoke(target, args);   
  13.             return massageReturnTypeIfNecessary(proxy, target, retVal);   
  14.         }   
  15.     }   
  16.   
  17.   
  18.     /**  
  19.      * Method interceptor used for static targets with no advice chain, when the  
  20.      * proxy is to be exposed.  
  21.      */  
  22.     private static class StaticUnadvisedExposedInterceptor implements MethodInterceptor, Serializable {   
  23.   
  24.         private final Object target;   
  25.   
  26.         public StaticUnadvisedExposedInterceptor(Object target) {   
  27.             this.target = target;   
  28.         }   
  29.   
  30.         public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {   
  31.             Object oldProxy = null;   
  32.             try {   
  33.                 oldProxy = AopContext.setCurrentProxy(proxy);   
  34.                 Object retVal = methodProxy.invoke(target, args);   
  35.                 return massageReturnTypeIfNecessary(proxy, target, retVal);   
  36.             }   
  37.             finally {   
  38.                 AopContext.setCurrentProxy(oldProxy);   
  39.             }   
  40.         }   
  41.     }   
  42.   
  43.   
  44.     /**  
  45.      * Interceptor used to invoke a dynamic target without creating a method  
  46.      * invocation or evaluating an advice chain. (We know there was no advice  
  47.      * for this method.)  
  48.      */  
  49.     private class DynamicUnadvisedInterceptor implements MethodInterceptor, Serializable {   
  50.   
  51.         public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {   
  52.             Object target = advised.getTargetSource().getTarget();   
  53.             try {   
  54.                 Object retVal = methodProxy.invoke(target, args);   
  55.                 return massageReturnTypeIfNecessary(proxy, target, retVal);   
  56.             }   
  57.             finally {   
  58.                 advised.getTargetSource().releaseTarget(target);   
  59.             }   
  60.         }   
  61.     }   
  62.   
  63.   
  64.     /**  
  65.      * Interceptor for unadvised dynamic targets when the proxy needs exposing.  
  66.      */  
  67.     private class DynamicUnadvisedExposedInterceptor implements MethodInterceptor, Serializable {   
  68.   
  69.         public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {   
  70.             Object oldProxy = null;   
  71.             Object target = advised.getTargetSource().getTarget();   
  72.             try {   
  73.                 oldProxy = AopContext.setCurrentProxy(proxy);   
  74.                 Object retVal = methodProxy.invoke(target, args);   
  75.                 return massageReturnTypeIfNecessary(proxy, target, retVal);   
  76.             }   
  77.             finally {   
  78.                 AopContext.setCurrentProxy(oldProxy);   
  79.                 advised.getTargetSource().releaseTarget(target);   
  80.             }   
  81.         }   
  82.     }  
private static class StaticUnadvisedInterceptor implements MethodInterceptor, Serializable {

		private final Object target;

		public StaticUnadvisedInterceptor(Object target) {
			this.target = target;
		}

		public Object intercept(Object proxy, Method method, Object[] args,
				MethodProxy methodProxy) throws Throwable {

			Object retVal = methodProxy.invoke(target, args);
			return massageReturnTypeIfNecessary(proxy, target, retVal);
		}
	}


	/**
	 * Method interceptor used for static targets with no advice chain, when the
	 * proxy is to be exposed.
	 */
	private static class StaticUnadvisedExposedInterceptor implements MethodInterceptor, Serializable {

		private final Object target;

		public StaticUnadvisedExposedInterceptor(Object target) {
			this.target = target;
		}

		public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
			Object oldProxy = null;
			try {
				oldProxy = AopContext.setCurrentProxy(proxy);
				Object retVal = methodProxy.invoke(target, args);
				return massageReturnTypeIfNecessary(proxy, target, retVal);
			}
			finally {
				AopContext.setCurrentProxy(oldProxy);
			}
		}
	}


	/**
	 * Interceptor used to invoke a dynamic target without creating a method
	 * invocation or evaluating an advice chain. (We know there was no advice
	 * for this method.)
	 */
	private class DynamicUnadvisedInterceptor implements MethodInterceptor, Serializable {

		public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
			Object target = advised.getTargetSource().getTarget();
			try {
				Object retVal = methodProxy.invoke(target, args);
				return massageReturnTypeIfNecessary(proxy, target, retVal);
			}
			finally {
				advised.getTargetSource().releaseTarget(target);
			}
		}
	}


	/**
	 * Interceptor for unadvised dynamic targets when the proxy needs exposing.
	 */
	private class DynamicUnadvisedExposedInterceptor implements MethodInterceptor, Serializable {

		public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
			Object oldProxy = null;
			Object target = advised.getTargetSource().getTarget();
			try {
				oldProxy = AopContext.setCurrentProxy(proxy);
				Object retVal = methodProxy.invoke(target, args);
				return massageReturnTypeIfNecessary(proxy, target, retVal);
			}
			finally {
				AopContext.setCurrentProxy(oldProxy);
				advised.getTargetSource().releaseTarget(target);
			}
		}
	}




我们自己也可以来试试
1.jdk proxy方式

先来一个接口
IHelloWorld.java

Java代码 复制代码
  1. package kris.aop.test;   
  2.   
  3. public interface IHelloWorld {   
  4.   
  5.     public void print(String name);   
  6.        
  7.     public void write(String sth);   
  8. }  
package kris.aop.test;

public interface IHelloWorld {

	public void print(String name);
	
	public void write(String sth);
}




再来一个实现

HelloWorld.java

Java代码 复制代码
  1. package kris.aop.test;   
  2.   
  3. public class HelloWorld implements IHelloWorld {   
  4.   
  5.     public void print(String name){   
  6.         System.out.println("HelloWorld "+name);   
  7.     }   
  8.   
  9.     public void write(String sth) {   
  10.         System.out.println("write "+sth);   
  11.            
  12.     }   
  13.   
  14. }  
package kris.aop.test;

public class HelloWorld implements IHelloWorld {

	public void print(String name){
		System.out.println("HelloWorld "+name);
	}

	public void write(String sth) {
		System.out.println("write "+sth);
		
	}

}



代理类

DefaultInvocationHandler.java

Java代码 复制代码
  1. package kris.aop.test;   
  2.   
  3. import java.lang.reflect.InvocationHandler;   
  4. import java.lang.reflect.Method;   
  5.   
  6. public class DefaultInvocationHandler implements InvocationHandler {   
  7.   
  8.     /**  
  9.      * 替换外部class调用的方法  
  10.      * obj      外部已经已经包装好InvocationHandler的实例  
  11.      * method   外部方法  
  12.      * args     方法参数  
  13.      */  
  14.     public Object invoke(Object obj, Method method, Object[] args)   
  15.             throws Throwable {   
  16.         String s1 []={"kris"};   
  17.         String s2 []={"anyone"};   
  18.         IHelloWorld ihw=new HelloWorld();   
  19.         System.out.println("start!");   
  20.         method.invoke(ihw,args);   
  21.         method.invoke(ihw,s1);   
  22.         Object o=method.invoke(ihw,s2);   
  23.         System.out.println("stop!");   
  24.         return o;   
  25.     }   
  26.   
  27. }  
package kris.aop.test;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class DefaultInvocationHandler implements InvocationHandler {

	/**
	 * 替换外部class调用的方法
	 * obj		外部已经已经包装好InvocationHandler的实例
	 * method	外部方法
	 * args		方法参数
	 */
	public Object invoke(Object obj, Method method, Object[] args)
			throws Throwable {
		String s1 []={"kris"};
		String s2 []={"anyone"};
		IHelloWorld ihw=new HelloWorld();
		System.out.println("start!");
		method.invoke(ihw,args);
		method.invoke(ihw,s1);
		Object o=method.invoke(ihw,s2);
		System.out.println("stop!");
		return o;
	}

}



测试类
Test.java

Java代码 复制代码
  1. package kris.aop.test;   
  2.   
  3. import java.lang.reflect.InvocationHandler;   
  4. import java.lang.reflect.Proxy;   
  5.   
  6. public class Test {   
  7.   
  8.     public static void main(String args []){   
  9.         Class clazz = new HelloWorld().getClass();   
  10.         ClassLoader cl = clazz.getClassLoader();   
  11.         Class classes [] = clazz.getInterfaces();   
  12.         InvocationHandler ih=new DefaultInvocationHandler();   
  13.         //用InvocationHandler给HelloWorld进行AOP包装   
  14.         IHelloWorld ihw=(IHelloWorld) Proxy.newProxyInstance(cl,classes,ih);   
  15.         ihw.print("test");   
  16.         ihw.write("test");   
  17.     }   
  18. }  
package kris.aop.test;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

public class Test {

	public static void main(String args []){
		Class clazz = new HelloWorld().getClass();
		ClassLoader cl = clazz.getClassLoader();
		Class classes [] = clazz.getInterfaces();
		InvocationHandler ih=new DefaultInvocationHandler();
		//用InvocationHandler给HelloWorld进行AOP包装
		IHelloWorld ihw=(IHelloWorld) Proxy.newProxyInstance(cl,classes,ih);
		ihw.print("test");
		ihw.write("test");
	}
}




2.用CGLIB包实现,首先不要忘了引入那个包

Java代码 复制代码
  1. package kris.aop.cglib.test;   
  2.   
  3. public class HelloWorld {   
  4.   
  5.     public void print(String name){   
  6.         System.out.println("HelloWorld "+name);   
  7.     }   
  8.   
  9.     public void write(String sth) {   
  10.         System.out.println("write "+sth);   
  11.            
  12.     }   
  13.     public void print(){   
  14.         System.out.println("HelloWorld");   
  15.     }   
  16.   
  17. }  
package kris.aop.cglib.test;

public class HelloWorld {

	public void print(String name){
		System.out.println("HelloWorld "+name);
	}

	public void write(String sth) {
		System.out.println("write "+sth);
		
	}
	public void print(){
		System.out.println("HelloWorld");
	}

}



代理类(没用内部类,看起来清楚点)

Java代码 复制代码
  1. package kris.aop.cglib.test;   
  2.   
  3. import java.lang.reflect.Method;   
  4.   
  5. import net.sf.cglib.proxy.MethodInterceptor;   
  6. import net.sf.cglib.proxy.MethodProxy;   
  7.   
  8. public class MethodInterceptorImpl implements MethodInterceptor {   
  9.   
  10.     public Object intercept(Object obj, Method method, Object[] args,   
  11.             MethodProxy proxy) throws Throwable {   
  12.   
  13.         System.out.println(method);   
  14.   
  15.         proxy.invokeSuper(obj, args);   
  16.   
  17.         return null;   
  18.     }   
  19. }  
package kris.aop.cglib.test;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class MethodInterceptorImpl implements MethodInterceptor {

	public Object intercept(Object obj, Method method, Object[] args,
			MethodProxy proxy) throws Throwable {

		System.out.println(method);

		proxy.invokeSuper(obj, args);

		return null;
	}
}



测试类

Java代码 复制代码
  1. package kris.aop.cglib.test;   
  2.   
  3. import net.sf.cglib.proxy.Enhancer;   
  4.   
  5. public class Test {   
  6.   
  7.     public static void main(String[] args) {   
  8.   
  9.         Enhancer enhancer = new Enhancer();   
  10.   
  11.         enhancer.setSuperclass(HelloWorld.class);   
  12.         //设置回调方法实现类   
  13.         enhancer.setCallback(new MethodInterceptorImpl());   
  14.         //实例化已经添加回调实现的HELLOWORLD实例   
  15.         HelloWorld my = (HelloWorld) enhancer.create();   
  16.   
  17.         my.print();   
  18.     }   
  19.   
  20. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值