spring aop内部兑现
spring aop内部实现AOP功能强大,但是spring是如何来实现AOP技术的呢? SPRING是通过动态代理来实现AOP的,SP
spring aop内部实现
AOP功能强大,但是spring是如何来实现AOP技术的呢?
SPRING是通过动态代理来实现AOP的,SPRING内部提供了2种实现机制
1.如果是有接口声明的类进行AOP,spring调用的是java.lang.reflection.Proxy类来做处理
org.springframework.aop.framework.JdkDynamicAopProxypublic 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.ReflectiveMethodInvocationpublic 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包和内部类来实现
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
package kris.aop.test;public interface IHelloWorld {public void print(String name);public void write(String sth);}
再来一个实现
HelloWorld.java
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
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
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包实现,首先不要忘了引入那个包
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");}}
代理类(没用内部类,看起来清楚点)
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;}}
测试类
package?kris.aop.cglib.test; ????import?net.sf.cglib.proxy.Enhancer; ????public?class?Test?{ ????????public?static?void?main(String[]?args)?{ ????????????Enhancer?enhancer?=?new?Enhancer(); ????????????enhancer.setSuperclass(HelloWorld.class); ??????????//设置回调方法实现类 ??????????enhancer.setCallback(new?MethodInterceptorImpl()); ??????????//实例化已经添加回调实现的HELLOWORLD实例 ??????????HelloWorld?my?=?(HelloWorld)?enhancer.create(); ????????????my.print(); ??????} ????}??