在前面的学习中,已经对AOP的代理对象的创建过程有了比较深入的理解。今天来看下,AOP代理对象的执行过程。
使用JdkDynamicAopProxy创建代理对象,原理是通过Proxy,newProxy来实现,上篇文章中已经注意到传入了this作为方法处理器,因为JdkDynamicAopProxy实现了InvocationHandler,因为通过JDK实现的代理对象,它的方法调用会被JdkDynamicAopProxy的invoke方法拦截:
在invoke方法中我们只需要关注以下几行代码:
if (chain.isEmpty()) {
// We can skip creating a MethodInvocation: just invoke the target directly
// Note that the final invoker must be an InvokerInterceptor so we know it does
// nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
// We need to create a method invocation...
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// Proceed to the joinpoint through the interceptor chain.
retVal = invocation.proceed();
}
在Invoke方法中会去获取拦截器链,如果拦截器链会空就直接通过反射调用方法。
AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
否则,包装成ReflectiveMethodInvocation,通过invocation.proceed();依次调用拦截器链并返回方法执行的结果。
CGLIB通过其设置的callBack来拦截目标对象的方法执行,其callBack是一个DynamicAdvisedInterceptor对象,实现了MethodInterceptor,因此CGLIB的代理对象会被DynamicAdvisedInterceptor的intercept拦截。
intercept方法中,主要关注下面几行代码
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = methodProxy.invoke(target, argsToUse);
}
else {
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
其实跟JDK代理是一样的,都是先获取拦截器链,然后判断拦截器链是否为空,如果为空那就直接执行方法,否则创建CglibMethodInvocation(也是ReflectiveMethodInvocation的实例),
通过proceed调用拦截器链然后返回方法结果。
这两种代理的执行过程设计和原理是一致:
有一点点区别:
1、对于目标方法的执行,jdk直接通过反射执行,而CGLIB,封装了MethodProxy来执行,据说性能会好一点。
2、拦截器链其实都是ReflectiveMethodInvocation,只不过CGLIB实现了特有的ReflectiveMethodInvocation。最终通过拦截器链的依次调用并且返回方法执行结果。