Spring深度解析-14、AOP代理对象的执行过程分析

在前面的学习中,已经对AOP的代理对象的创建过程有了比较深入的理解。今天来看下,AOP代理对象的执行过程。

JDK代理的invoke

使用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的intercept

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。最终通过拦截器链的依次调用并且返回方法执行结果。

你可能感兴趣的:(死磕spring源码)