31.AOP源码之CGLIB动态代理与intercept方法调用

401 阅读12分钟

8.CglibAopProxy#getProxy(java.lang.ClassLoader)

@Override
public Object getProxy(@Nullable ClassLoader classLoader){
    try {
        //从proxyFactory中获取代理类的class
        Class<?> rootClass = this.advised.getTargetClass();

        Class<?> proxySuperClass = rootClass;
        if (ClassUtils.isCglibProxyClass(rootClass)) {
            proxySuperClass = rootClass.getSuperclass();
            Class<?>[] additionalInterfaces = rootClass.getInterfaces();
            for (Class<?> additionalInterface : additionalInterfaces) {
                this.advised.addInterface(additionalInterface);
            }
        }
​
        validateClassIfNecessary(proxySuperClass, classLoader);
        Enhancer enhancer = createEnhancer();
        if (classLoader != null) {
            enhancer.setClassLoader(classLoader);
        if (classLoader instanceof SmartClassLoader &&
                ((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
                enhancer.setUseCache(false);
            }
        }
        enhancer.setSuperclass(proxySuperClass);
        enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
        enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
        enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy
                                                                (classLoader));
        //最重要的是DynamicAdvisedInterceptor
        Callback[] callbacks = getCallbacks(rootClass);
        Class<?>[] types = new Class<?>[callbacks.length];
        for (int x = 0; x < types.length; x++) {
            types[x] = callbacks[x].getClass();
        }
        enhancer.setCallbackFilter
                (new ProxyCallbackFilter(
                this.advised.getConfigurationOnlyCopy(), 
                this.fixedInterceptorMap, this.fixedInterceptorOffset));
                enhancer.setCallbackTypes(types);
​
        return createProxyClassAndInstance(enhancer, callbacks);
    }
    catch (CodeGenerationException | IllegalArgumentException ex) {
        throw new AopConfigException();
    }
    catch (Throwable ex) {
        throw new AopConfigException("Unexpected AOP exception", ex);
    }
}

0.获取代理类class

//从proxyFactory中获取被代理类的class
Class<?> rootClass = this.advised.getTargetClass();

我们可以看到,上边的代码,其实就是获取了目标类的class对象,说白了就是被代理类的class对象

那么获取这个对象干嘛呢?

cglib是采用继承目标类,重写父类方法的形式实现的动态代理,所以当然需要指定代理类的父类了

1.创建enhancer,设置代理类为父类

Enhancer enhancer = createEnhancer();
if (classLoader != null) {
    enhancer.setClassLoader(classLoader);
    if (classLoader instanceof SmartClassLoader &&
        ((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
        enhancer.setUseCache(false);
    }
}
enhancer.setSuperclass(proxySuperClass);
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));

构造了一个Enhancer,然后为Enhancer设置了各种属性,比如通过enhancer.setSuperclass(proxySuperClass)这行代码,就设置了代理类要实现的父类。

3.创建DynamicAdvisedInterceptor

对于Enhancer来说,除了设置要继承的父类外,还需要设置回调,其实就是callbacks,此时我们看到上边的代码中,有一行获取回调数组的方法,就是Callback[] callbacks = getCallbacks(rootClass),我们就来看看这里是怎么来获取回调数组的吧,此时getCallbacks()代码如下:

private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
        // AOP回调需要用到的拦截器
        //advised是我们的proxyFactory
        //里面封装了当前类所有可用的advisor
        Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);
        // 省略部分代码
        // 创建拦截器数组
        Callback[] mainCallbacks = new Callback[] {
                        aopInterceptor,  
                        targetInterceptor,  
                        new SerializableNoOp(),  
                        targetDispatcher, this.advisedDispatcher,
                        new EqualsInterceptor(this.advised),
                        new HashCodeInterceptor(this.advised)
        };
        Callback[] callbacks;
        if (isStatic && isFrozen) {
            //省略部分代码
        }
        else {
            // 设置回调拦截器数组给callbacks
            callbacks = mainCallbacks;
        }
        return callbacks;
}

这里的代码非常简单,其实就是先创建了一个DynamicAdvisedInterceptor拦截器的实例aopInterceptor

接着手动构建了一个回调数组mainCallbacks,将一堆拦截器放入这个回调数组中,其中就包括刚才创建的aopInterceptor拦截器,最后会将回调数组mainCallbacks赋值给callbacks并返回。

而这个callbacks中的拦截器,就是cglib代理对象中的方法被调用时需要回调的拦截器,这些拦截器中,有一个极为重要的拦截器aopInterceptor,aopInterceptor的类型是DynamicAdvisedInterceptor拦截器,大家这里先有个印象,随着后边分析越来越深入,自然就知道这个拦截器为什么如此重要了。

4.拦截器中包含了固定的7个Callback

 
/*
DynamicAdvisedInterceptor封装了我们切面和事务的advisor
callbacks = {Callback[7]@3006}
0 = {CglibAopProxy$DynamicAdvisedInterceptor@2967} //注意这里
1 = {CglibAopProxy$StaticUnadvisedInterceptor@2981}
2 = {CglibAopProxy$SerializableNoOp@3013}
3 = {CglibAopProxy$StaticDispatcher@2989}
4 = {CglibAopProxy$AdvisedDispatcher@2902}
5 = {CglibAopProxy$EqualsInterceptor@3014}
6 = {CglibAopProxy$HashCodeInterceptor@3015}
*/

/****
DynamicAdvisedInterceptor是我们的aopInterceptor从中可以看到我们的advisors

使用生成的代理类proxyClass,通过newInstance()方法进一步生成了代理类的实例proxyInstance,最后将回调数组callbacks设置到代理类proxyInstance中。


到这里,cglib代理才算是真正创建成功了,此时我们知道,在回调数组callbacks中,有一个极为重要的拦截器,那就是DynamicAdvisedInterceptor,当cglib代理类实例中的方法被调用时,那么就会回调到这个拦截器DynamicAdvisedInterceptor,此时这个拦截器就会开始执行增强方法和目标方法。
DynamicAdvisedInterceptor中的advisors属性 可以发现事务在最后面
****/

5.根据enhancer生成字节码,动态加载

@Override
protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
    Class<?> proxyClass = enhancer.createClass();
    Object proxyInstance = null;

    if (objenesis.isWorthTrying()) {
        try {
            proxyInstance = objenesis.newInstance(proxyClass, enhancer.getUseCache());
        }catch (Throwable ex) {

        }
    }

    if (proxyInstance == null) {
        // Regular instantiation via default constructor...
        try {
            Constructor<?> ctor = (this.constructorArgs != null ?
                            proxyClass.getDeclaredConstructor(this.constructorArgTypes) :
                            proxyClass.getDeclaredConstructor());
            ReflectionUtils.makeAccessible(ctor);
            proxyInstance = (this.constructorArgs != null ?
                            ctor.newInstance(this.constructorArgs) : ctor.newInstance());
        } catch (Throwable ex) {
            throw new AopConfigException();
        }
    }

    ((Factory) proxyInstance).setCallbacks(callbacks);
    return proxyInstance;
}

我们可以看到,这里首先调用Enhancer的createClass()方法生成了代理类proxyClass

6.创建代理对象

接着使用生成的代理类proxyClass,通过newInstance()方法进一步生成了代理类的实例proxyInstance,最后将回调数组callbacks设置到代理类proxyInstance中。

到这里,cglib代理才算是真正创建成功了,此时我们知道,在回调数组callbacks中,有一个极为重要的拦截器,那就是DynamicAdvisedInterceptor,当cglib代理类实例中的方法被调用时,那么就会回调到这个拦截器DynamicAdvisedInterceptor,此时这个拦截器就会开始执行增强方法和目标方法。

7.DynamicAdvisedInterceptor#intercept

通过前边的学习,我们知道,当调用jdk代理中的方法时,会回调到JdkDynamicAopProxy的invoke()方法,那么cglib代理中的方法被调用时,会回调到哪个类的哪个方法呢?

在为cglib代理创建拦截器回调数组时,其实里边有一个极为重要的拦截器。这个极为重要的拦截器其实就是DynamicAdvisedInterceptor,这个就是cglib代理回调需要用到的拦截器,说白了就是,当cglib代理中的方法被调用时,其实就会回调到这个DynamicAdvisedInterceptor。

现在呢,我们知道会回调到DynamicAdvisedInterceptor类了,那么具体是回调这个类的哪个方法呢?

我们上节讲过,在为cglib代理创建拦截器回调数组时,其实里边有一个极为重要的拦截器,如下图:

Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);

现在呢,我们知道会回调到DynamicAdvisedInterceptor类了,那么具体是回调这个类的哪个方法呢?

可以看到,当时我们的核心逻辑,都放在了intercept()方法中

所以根据之前我们玩儿字节码增强器Enhancer的经验,可以知道,当cglib代理的方法被调用时,其实是会回调到DynamicAdvisedInterceptor类的intercept()方法的!

那还有啥好说的,我们来看下DynamicAdvisedInterceptor类的intercept()方法呗。

其实啊,这个DynamicAdvisedInterceptor其实是CglibAopProxy中的一个内部类。

而DynamicAdvisedInterceptor的intercept()方法,代码如下:

org.springframework.aop.framework.CglibAopProxy.DynamicAdvisedInterceptor#intercept

@Override
@Nullable
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();
    try {
        //判断是否需要暴露代理类
        if (this.advised.exposeProxy) {
            oldProxy = AopContext.setCurrentProxy(proxy);
            setProxyContext = true;
        }
        target = targetSource.getTarget();
        Class<?> targetClass = (target != null ? target.getClass() : null);
    /***
    封装chain
    this.advised是我们的ProxyFactory
    ProxyFactory封装了各种参数比如被代理类的实例以及advisors
    advisor中又封装了增强方法和增强方法的切面表达式。
    ***/
    List<Object> chain = 
        this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
        Object retVal;
        // Check whether we only have one InvokerInterceptor: that is,
        // no real advice, but just reflective invocation of the target.
        if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
            Object[] argsToUse =AopProxyUtils.adaptArgumentsIfNecessary(method, args);
            retVal = methodProxy.invoke(target, argsToUse);
        }
        else {
            // 创建1个CglibMethodInvocation 父类是 ReflectiveMethodInvocation
            //注意proceed方法的调用
            retVal = new CglibMethodInvocation
                            (proxy, target, method, args, targetClass, chain,methodProxy)
                            .proceed();
        }
        retVal = processReturnType(proxy, target, method, retVal);
        return retVal;
    }finally {
        if (target != null && !targetSource.isStatic()) {
            targetSource.releaseTarget(target);
        }
        if (setProxyContext) {
            // Restore old proxy.
            AopContext.setCurrentProxy(oldProxy);
        }
    }
}

8.获取拦截器链

cglib代理是如何获取拦截器链的?

那么首先就会来执行下边这块代码

//被代理类的实例
TargetSource targetSource = this.advised.getTargetSource();
try {
//判断是否需要暴露代理类
if (this.advised.exposeProxy) {
    oldProxy = AopContext.setCurrentProxy(proxy);
    setProxyContext = true;
}

target = targetSource.getTarget();

这块代码其实很简单,就是用来获取目标类的,其实最终获取的这个目标类targetClass的值就是代理类。在分析jdk代理的invoke()方法时,也有类似的代码,非常简单。

好,获取到目标类后,我们继续往下看,此时就会看到下边这行代码

List<Object> chain = this.advised
                         .getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

看到上边这行代码,大家有没有觉得很熟悉?咋感觉这里获取拦截器链的代码,在分析jdk代理时见过呢?

带着这个疑问,我们点进去这个getInterceptorsAndDynamicInterceptionAdvice()方法来看下

@Override
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
                Advised config, Method method, @Nullable Class<?> targetClass) {

    AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
    //获取proxyFactory的advisors
    Advisor[] advisors = config.getAdvisors();
    List<Object> interceptorList = new ArrayList<>(advisors.length);
    Class<?> actualClass 
    = (targetClass != null ? targetClass : method.getDeclaringClass());
    Boolean hasIntroductions = null;
    //遍历advisors
    for (Advisor advisor : advisors) {
        //判断类级别匹配
        if (advisor instanceof PointcutAdvisor) {
            PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
            if (config.isPreFiltered() || pointcutAdvisor.getPointcut()
                                                .getClassFilter().matches(actualClass)) {
                //方法匹配器
                MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
                boolean match;
                //方法签名匹配
                if (mm instanceof IntroductionAwareMethodMatcher) {
                    if (hasIntroductions == null) {
                        hasIntroductions = hasMatchingIntroductions(advisors, actualClass);
                    }
                    match = ((IntroductionAwareMethodMatcher) mm)
                                .matches(method, actualClass, hasIntroductions);
                }else {
                    match = mm.matches(method, actualClass);
                }
                //匹配通过
                if (match) {
                    //获取拦截器
                    MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
                    if (mm.isRuntime()) {
                        for (MethodInterceptor interceptor : interceptors) {
                            interceptorList
                             .add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
                        }
                    } else {
                        interceptorList.addAll(Arrays.asList(interceptors));
                    }
                }
            }
        }else if (advisor instanceof IntroductionAdvisor) {
            IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
            if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
                Interceptor[] interceptors = registry.getInterceptors(advisor);
                interceptorList.addAll(Arrays.asList(interceptors));
            }
        }else {
            Interceptor[] interceptors = registry.getInterceptors(advisor);
            interceptorList.addAll(Arrays.asList(interceptors));
        }
    }
    return interceptorList;
}
@Override
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
    List<MethodInterceptor> interceptors = new ArrayList<>(3);
    //获取Advice
    Advice advice = advisor.getAdvice();
    //判断advice的类型 是MethodInterceptor 直接加入
    if (advice instanceof MethodInterceptor) {
        interceptors.add((MethodInterceptor) advice);
    }

    //不是MethodInterceptor类型 使用适配器包装
    for (AdvisorAdapter adapter : this.adapters) {
        if (adapter.supportsAdvice(advice)) {
            interceptors.add(adapter.getInterceptor(advisor));
        }
    }
    if (interceptors.isEmpty()) {
        throw new UnknownAdviceTypeException(advisor.getAdvice());
    }
    return interceptors.toArray(new MethodInterceptor[0]);
}

@Override
@Nullable
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {

    Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
    validate(candidateAspectClass);

    AspectJAnnotation<?> aspectJAnnotation
        =AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
    if (aspectJAnnotation == null) {
        return null;
    }

    // If we get here, we know we have an AspectJ method.
    // Check that it's an AspectJ-annotated class
    if (!isAspect(candidateAspectClass)) {
        throw new AopConfigException("Advice must be declared inside an aspect type: " +
                        "Offending method '" + candidateAdviceMethod + "' in class [" +
                        candidateAspectClass.getName() + "]");
    }

    if (logger.isDebugEnabled()) {
        logger.debug("Found AspectJ method: " + candidateAdviceMethod);
    }

    AbstractAspectJAdvice springAdvice;

    switch (aspectJAnnotation.getAnnotationType()) {
        case AtPointcut:
            if (logger.isDebugEnabled()) {
                logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
            }
            return null;
        case AtAround:
            springAdvice = new AspectJAroundAdvice(
                            candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
            break;
        case AtBefore:
            springAdvice = new AspectJMethodBeforeAdvice(
                            candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
            break;
        case AtAfter:
            springAdvice = new AspectJAfterAdvice(
                            candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
            break;
        case AtAfterReturning:
            springAdvice = new AspectJAfterReturningAdvice
                            (candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
            AfterReturning afterReturningAnnotation 
                        = (AfterReturning) aspectJAnnotation.getAnnotation();
            if (StringUtils.hasText(afterReturningAnnotation.returning())) {
                springAdvice.setReturningName(afterReturningAnnotation.returning());
            }
            break;
        case AtAfterThrowing:
            springAdvice = new AspectJAfterThrowingAdvice(
                        candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
            AfterThrowing afterThrowingAnnotation 
                        = (AfterThrowing) aspectJAnnotation.getAnnotation();
            if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
                springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
            }
            break;
        default:
            throw new UnsupportedOperationException(
                                "Unsupported advice type on method: " + candidateAdviceMethod);
    }

    // Now to configure the advice...
    springAdvice.setAspectName(aspectName);
    springAdvice.setDeclarationOrder(declarationOrder);
    String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
    if (argNames != null) {
        springAdvice.setArgumentNamesFromStringArray(argNames);
    }
    springAdvice.calculateArgumentBindings();

    return springAdvice;
}

看到上边的代码后,简直惊呆了,这个不就是我们分析jdk代理时,获取拦截器链的代码吗?

难道cglib代理在获取拦截器链时,和jdk代理调用的是同一个方法?

哈哈,同学,你猜对了,确实是这样的,cglib代理和jdk代理在获取拦截器链时,调用的确实是同一个方法,说白了就是获取拦截器链的流程是完全一模一样的!惊不惊喜意不意外?哈哈哈

那现在就好办了,之前我们分析jdk代理时,重点分析过这个获取拦截器链的流程。

在获取拦截器链时,首先会将目标方法作为缓存key,到缓存中看下对应的拦截器链存不存在,如果存在的话,那么就将拦截器链作为结果返回。

而如果缓存中不存在拦截器链的话,那么就会从ProxyFactory中获取目标类级别对应的增强,接着去遍历这些增强,遍历的时候,会先来看下目标方法所在的类和增强是否匹配,如果类级别匹配的话,那么会接着看下目标方法与切点表达式在方法参数、方法名称、方法抛出异常、方法返回值维度是否都可以精确匹配,最后将匹配上的增强收集起来。

接着就开始处理这些匹配成功的增强,简单来说,就是将这些匹配成功增强中的增强方法统一封装为拦截器,然后这些拦截器会统一放到一个拦截器集合中,而这个拦截器集合其实就是拦截器链,然后就会将这个拦截器链放到缓存中,最后会将这个拦截器链作为结果返回。

这个就是获取拦截器链的整个过程,我们简单回顾了一遍,至于里边的一些细节,我们之前都详细讲过,这里就不再赘述了。

9.执行拦截器链

cglib代理是如何执行拦截器链的?

那么获取到拦截器链之后,下一步该做什么了呢?我们继续往下看,获取拦截器之后,就要执行下边这块代码了。

if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {

    Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
    retVal = methodProxy.invoke(target, argsToUse);
}else {
    // 创建1个CglibMethodInvocation 父类是 ReflectiveMethodInvocation
    retVal = new CglibMethodInvocation
                (proxy, target, method, args, targetClass, chain, methodProxy)
                //注意proceed方法的调用
                .proceed();
}
    retVal = processReturnType(proxy, target, method, retVal);
    return retVal;

大家可以看到,其实这里的逻辑和jdk代理的逻辑差不多,都是一样的套路。

就是先看下拦截器链chain是不是为空,如果为空的话,说明此时没有增强需要执行,那此时直接执行目标方法就完事儿了。而如果拦截器链chain不为空,那此时就需要来执行拦截器链中的增强方法了。

通过上图,可以看到,这里先通过构造方法创建了一个CglibMethodInvocation类的实例.

接着调用了这个实例的proceed()方法。

private static class CglibMethodInvocation extends ReflectiveMethodInvocation {

    @Nullable
    private final MethodProxy methodProxy;

    public CglibMethodInvocation(Object proxy, @Nullable Object target, Method method,
                    Object[] arguments, @Nullable Class<?> targetClass,
            List<Object> interceptorsAndDynamicMethodMatchers, MethodProxy methodProxy) {

        super(proxy, target, method, arguments, targetClass, 
                                                    interceptorsAndDynamicMethodMatchers);

        this.methodProxy = (Modifier.isPublic(method.getModifiers()) 
         &&method.getDeclaringClass() != Object.class 
         &&!AopUtils.isEqualsMethod(method)
         &&!AopUtils.isHashCodeMethod(method) 
         &&!AopUtils.isToStringMethod(method) ?  methodProxy : null);
    }

    @Override
    protected Object invokeJoinpoint() throws Throwable {
        if (this.methodProxy != null) {
            return this.methodProxy.invoke(this.target, this.arguments);
        }
        else {
            return super.invokeJoinpoint();
        }
    }
}

CglibMethodInvocation主要依赖于父类ReflectiveMethodInvocation的构造方法完成的初始化,其中比较重要的,就是将拦截器链chain最终赋值给了成员变量interceptorsAndDynamicMethodMatchers。

在CglibMethodInvocation的实例构建完成后,下一步就要调用CglibMethodInvocation的proceed()方法。

也就是说,接下来要调用CglibMethodInvocation类的proceed()方法了,那这时候,我们来看下proceed()方法的代码呗。

其实proceed()方法关键就一行代码,那就是super.proceed(),说白了就是依赖于父类的proceed()方法完成了功能。

那么父类是谁呢?

其实我们刚刚分析过,这个父类其实就是ReflectiveMethodInvocation,那还有啥好说的,我们来看下ReflectiveMethodInvocation类中的proceed()方法呗,此时我们会看到下边的代码

@Override
@Nullable
public Object proceed() throws Throwable {
    // We start with an index of -1 and increment early.
    // 初始currentInterceptorIndex为-1,每调用一次proceed就把currentInterceptorIndex+1
    if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
        // 当调用次数 = 拦截器个数时
        // 1. 触发当前method方法
        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 {
            // 2. 普通拦截器,直接触发拦截器invoke方法
            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);
    }
}

这个proceed()方法,就是之前我们分析jdk代理执行拦截器链时,不断递归调用的那个proceed()方法!

只不过当时jdk代理的玩儿法是直接调用ReflectiveMethodInvocation类的proceed()方法。

在JdkDynamicAopProxy中的处理,是直接new了一个ReflectiveMethodInvocation实例,接着调用了这个实例proceed()方法。

而在这里cglib的处理,其实就是先构造了一个CglibMethodInvocation的实例,而这个CglibMethodInvocation其实是ReflectiveMethodInvocation的子类,接着会调用子类CglibMethodInvocation的proceed()。

其实在子类CglibMethodInvocation的proceed()方法中,其实还是依赖于父类ReflectiveMethodInvocation的proceed()方法完成的功能,所以cglib在执行拦截器链时,本质还是调用了ReflectiveMethodInvocation的proceed()方法,其实和jdk代理执行拦截器链是一样的套路!

后续的流程,其实就是不断的递归调用ReflectiveMethodInvocation的proceed()方法,从而将所有的拦截器串成一根链条,这样拦截器之间就会按照一定的顺序,执行各自的增强方法。

在满足递归结束的条件后,首先会执行目标方法,而执行完目标方法后,接着就会层层返回执行结果,接着其他的拦截器就会分别执行自己内部的增强方法了,执行拦截器链的整个过程