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


highlight: arduino-light

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

```java @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

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

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

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

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

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

java 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()代码如下:

java 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

```java

/* 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生成字节码,动态加载

```java @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

java @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()方法时,也有类似的代码,非常简单。

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

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

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

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

```java @Override public List 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;

} ```

```java @Override public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException { List 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]);

} ```

```java

@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()方法。

```java 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()方法呗,此时我们会看到下边的代码

java @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()方法,从而将所有的拦截器串成一根链条,这样拦截器之间就会按照一定的顺序,执行各自的增强方法。

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值