接上文 Spring AOP原理之建立AopProxy代理对象
在Spring AOP通过JDK的Proxy方式或CGLIB方式生成代理对象的时候,相关的拦截器已经配置到代理对象中去了,拦截器在代理对象中起作用是通过对这些方法的回调来完成的。如果使用
JDK的Proxy
来生成代理对象,那么需要通过InvocationHandler来设置拦截器回调.而如果使用CGLIB
来生成代理对象,就需要根据CGLIB的使用要求.通过DynamicAdvisedlnterceptor来完成回调。
上篇文章中,在JdkDynamicAopProxy
生成代理对象的时候,我们可以看到这样的源码:
//调用JDK生成代理对象
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
这里的this
参数对应的是InvocationHandler
对象,InvocationHandler
是JDK
定义的反射类的一个接口,这个接口定义了invoke方法。
public interface InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
}
而这个invoke
方法是作为JDK Proxy
代理对象进行拦截的回调入口出现的。在JdkDynamicAopProxy
中实现TlnvocationHandler
接口,也就是说当Proxy
对象的代理方法被调用时.JdkDynamicAopProxy
的invoke
方法作为Proxy
对象的回调函数被触发,从而通过invoke的其体实现。来完成对目标对象方法调用的拦截或者说功能增强的工作。
JdkDynamicAopProxy实现的该方法如下:
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
TargetSource targetSource = this.advised.targetSource;
Object target = null;
Object var13;
try {
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
//如果目标对象没有实现Object类的基本方法:equals
Boolean var19 = this.equals(args[0]);
return var19;
}
if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
//如果目标对象没有实现Object类的基本方法:hashCode
Integer var18 = this.hashCode();
return var18;
}
if (method.getDeclaringClass() == DecoratingProxy.class) {
//
Class var17 = AopProxyUtils.ultimateTargetClass(this.advised);
return var17;
}
Object retVal;
if (!this.advised.opaque && method.getDeclaringClass().isInterface() && method.getDeclaringClass().isAssignableFrom(Advised.class)) {
//根据代理对象的配置来调用服务
retVal = AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
return retVal;
}
if (this.advised.exposeProxy) {
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
//得到目标对象
target = targetSource.getTarget();
Class> targetClass = target != null ? target.getClass() : null;
//获得定义好的拦截器链
List
对Proxy
对象的代理设里是在invoke
方法中完成的.这些设里包括获取目标对象、拦截器链.同时把这些对象作为愉入,创建了ReflectiveMethodlnvocation
对象,通过这个ReflectiveMethodlnvocation
对象来完成对AOP
功能实现的封装。在这个invoke
方法中,包含了一个完整的拦截器链对目标对象的拦截过程。比如获得拦截器链并对拦截器链中的拦截器进行配置,逐个运行拦截器链里的拦截增强,直到最后对目标对象方法的运行等。
CgIibAopProxy
的intercept
回调方法的实现和JdkDynamicAopProxy
的回调实现是非常类似的,只是在CghibAopProxy
中构造DynamicAdvisedInterceptor
对象来完成拦截器链的调用,而在JdkDynamicAopProxy
中是通过构造ReflectiveMethodInvocation
对象来完成这个功能的。
DynamicAdvisedInterceptor
通过实现MethodInterceptor
接口来完成:
import java.lang.reflect.Method;
public interface MethodInterceptor extends Callback {
Object intercept(Object var1, Method var2, Object[] var3, MethodProxy var4) throws Throwable;
}
其实现如下:
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
Object target = null;
TargetSource targetSource = this.advised.getTargetSource();
Object var16;
try {
if (this.advised.exposeProxy) {
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
//得到目标对象
target = targetSource.getTarget();
Class> targetClass = target != null ? target.getClass() : null;
//从advised中取得配置好的AOP通知
List
从上面可以看出,拦截器的实现逻辑是一样的。包括目标对象的调用,AOP拦截器链的调用以及配置通知器等。