JdkDynamicAopProxy 实现了 InvocationHandler 接口,所以在创建代理对象的时候传递了 this
// jdk动态代理创建代理对象return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
进入方法调用
@Override@Nullablepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("jdk aop 拦截方法:" + method.getName());Object oldProxy = null;boolean setProxyContext = false;// 代理目标TargetSource targetSource = this.advised.targetSource;// 代理目标对象Object target = null;try {if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {// 如何代理接口没有定义equals方法,则调用JdkDynamicAopProxy的重写的equals方法// The target does not implement the equals(Object) method itself.return equals(args[0]);} else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {// 同上// The target does not implement the hashCode() method itself.return hashCode();} else if (method.getDeclaringClass() == DecoratingProxy.class) {// There is only getDecoratedClass() declared -> dispatch to proxy config.return AopProxyUtils.ultimateTargetClass(this.advised);} else if (!this.advised.opaque&& method.getDeclaringClass().isInterface()&& method.getDeclaringClass().isAssignableFrom(Advised.class)) {// Service invocations on ProxyConfig with the proxy config.../*opaque:表示代理对象是否可以转换成 Advised 类型,默认为false;被代理类是否接口;被代理类是否实现了接口Advised; 通常情况下被代理的对象或者接口都不会*/return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);}// 返回结果Object retVal;// 如果暴露代理的话,放到 currentProxy(ThreadLocal)中if (this.advised.exposeProxy) {// Make invocation available if necessary.oldProxy = AopContext.setCurrentProxy(proxy);setProxyContext = true;}// Get as late as possible to minimize the time we "own" the target,// in case it comes from a pool.// 获取代理对象target = targetSource.getTarget();// 代理对象的Class对象Class<?> targetClass = (target != null ? target.getClass() : null);// Get the interception chain for this method.// 获取方法拦截的调用链List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);// Check whether we have any advice. If we don't, we can fallback on direct// reflective invocation of the target, and avoid creating a MethodInvocation.if (chain.isEmpty()) {/*We can skip creating a MethodInvocation: just invoke the target directlyNote that the final invoker must be an InvokerInterceptor so we know it doesnothing 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 {// 创建MethodInvocation,对方法进行拦截调用MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);// Proceed to the joinpoint through the interceptor chain.retVal = invocation.proceed();}// Massage return value if necessary.// 整理返回值Class<?> returnType = method.getReturnType();if (retVal != null&& retVal == target&& returnType != Object.class&& returnType.isInstance(proxy)&& !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {// Special case: it returned "this" and the return type of the method// is type-compatible. Note that we can't help if the target sets// a reference to itself in another returned object.retVal = proxy;} else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {throw new AopInvocationException("Null return value from advice does not match primitive return type for:" + method);}return retVal;} finally {if (target != null && !targetSource.isStatic()) {// Must have come from TargetSource.targetSource.releaseTarget(target);}if (setProxyContext) {// Restore old proxy.AopContext.setCurrentProxy(oldProxy);}}}
过程:
- 首先判断方法是否为 equals 或者 hashcode,如果被代理对象没有实现的话,使用代理对象重写的方法;
 - 判断如果父类是 DecoratingProxy ,直接调用目标对象;
 - 判断被代理类是否为接口,是否为Advised或者父接口,是否可以转换成Advised类型,满足的话,直接调用目标方法;
 - 如果要暴露代理对象的话,将代理配置放到 ThreadLocal 中,实现该线程下共享;
 - 获取代理对象,获取方法拦截的调用链;
 - 如果调用链为空,那么直接调用目标方法;
 - 调用链不为空,创建 MethodInvocation 对象,执行方法的拦截器;(这里用到责任链模式)
 - 整理最终返回值,返回。
 
执行方法拦截在 ReflectiveMethodInvocation 对象中执行,首先看下该类父类关系:
入口方法 proceed() 由接口 Joinpoint 提供.
package org.aopalliance.intercept;import java.lang.reflect.AccessibleObject;public interface Joinpoint {// 继续进行链中的下一个拦截器。Object proceed() throws Throwable;// 被代理对象Object getThis();AccessibleObject getStaticPart();}
@Override@Nullablepublic 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;Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());if (dm.methodMatcher.matches(this.method, 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.// 普通的拦截器:/*ExposeInvocationInterceptor、DelegatePerTargetObjectIntroductionInterceptor、MethodBeforeAdviceInterceptor、AspectJAroundAdvice、AspectJAfterAdvice*/return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);}}
这是一个递归方法,递归执行拦截器方法。根据集合下标依次执行。当执行到最后一个拦截器,就是递归的出口,直接执行目标对象方法。
拿到一个拦截器,判断是否为 InterceptorAndDynamicMethodMatcher (内部框架类,将 MethodInterceptor 实例与 MethodMatcher 组合在一起)
如果不是的话,那么直接执行拦截器方法,并且带着当前 ReflectiveMethodInvocation 对象;
我们的拦截方法会被解析成 MethodInterceptor 所以这个分支不会走。 
比如我们的前置增强对应的实例为:org.springframework.aop.aspectj.AspectJMethodBeforeAdvice
那么就会进入这个拦截器的方法
// 该方法由 MethodInterceptor 提供@Overridepublic Object invoke(MethodInvocation mi) throws Throwable {this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());return mi.proceed();}
首先执行增强方法,然后再继续执行拦截链上的下一个拦截方法。
