30.AOP源码之JDK代理对象invoke方法调用


highlight: arduino-light

在jdk动态代理中invoke方法中的三个参数分别是什么呢?

以addProduct()方法为例,此时会执行这行代码:

java super.h.invoke(this, m3, new Object[]{var1})

第一个参数this没啥好说的,就是当前代理对象自己,也就是\$Proxy13类的对象,

而第二个参数m3是在一个static代码块中初始化的,初始化代码为

java m3 = Class.forName("com.ruyuan.aop.service.ProductService") .getMethod("addProduct", Class.forName("com.ruyuan.aop.model.Product"))。

说白了就是使用反射获取到了addProduct(Product product)方法的method对象。

也就是目标方法的method对象。

而第三个参数很简单,其实就是将入参封装到了一个数组中。

好了,也就是说当调用到代理对象的方法时,就会回调到JdkDynamicAopProxy类的invoke()方法,同时会将代理对象本身、目标方法的method对象以及参数数组都传递给invoke()方法,接着invoke()方法就利用传递进来的参数来做各种处理了。

```java @Override @Nullable public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object oldProxy = null; boolean setProxyContext = false; ​ TargetSource targetSource = this.advised.targetSource; Object target = null; ​ try { if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) { return equals(args[0]); }else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) { return hashCode(); }else if (method.getDeclaringClass() == DecoratingProxy.class) { return AopProxyUtils.ultimateTargetClass(this.advised); }else if (!this.advised.opaque && method.getDeclaringClass().isInterface() && method.getDeclaringClass().isAssignableFrom(Advised.class)) { return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args); } ​ Object retVal; //是否需要暴露被代理类 if (this.advised.exposeProxy) { oldProxy = AopContext.setCurrentProxy(proxy); setProxyContext = true; }

//获取原始的target 即没有经过代理的对象
    target = targetSource.getTarget();
    Class<?> targetClass = (target != null ? target.getClass() : null);

​ ​ //根据目标方法的method对象和类名以及advisors经过一通处理获取到了最终的拦截器链。 List chain = this .advised .getInterceptorsAndDynamicInterceptionAdvice (method, targetClass); ​ //如果拦截器链chain为空的话,那么就直接执行目标方法 if (chain.isEmpty()) { Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args); /* 核心代码就是method.invoke(target, args) 说白了就是通过反射执行目标方法。 */ retVal =AopUtils.invokeJoinpointUsingReflection (target, method, argsToUse); }else { //创建1个ReflectiveMethodInvocation MethodInvocation invocation = new ReflectiveMethodInvocation (proxy, target, method, args, targetClass, chain);

//这个是一个chain触发责任链
        //真正去执行拦截器链。
        //不管怎么样最后还是会调用目标类的原始方法
        retVal = invocation.proceed();
    }

​ Class> returnType = method.getReturnType(); if (retVal != null && retVal == target && returnType != Object.class && returnType.isInstance(proxy) && !RawTargetAccess.class.isAssignableFrom (method.getDeclaringClass())) { retVal = proxy; }else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) { throw new AopInvocationException(); } return retVal; } finally { if (target != null && !targetSource.isStatic()) { targetSource.releaseTarget(target); } if (setProxyContext) { AopContext.setCurrentProxy(oldProxy); } } } ```

获取拦截器链

method根据目标方法的method对象

targetclass被代理类的类名

java public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) { MethodCacheKey cacheKey = new MethodCacheKey(method); List<Object> cached = this.methodCache.get(cacheKey); if (cached == null) { //this是谁? //是AdvisedSupport //也就是我们的ProxyFactory cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice( this, method, targetClass); this.methodCache.put(cacheKey, cached); } return cached; }

在这个方法中,首先将method作为入参,构建出来了一个缓存key对象MethodCacheKey,然后使用这个缓存key从缓存methodCache中获取拦截器链。

那这个methodCache是什么数据结构呢?目前为止看起来应该是一个Map,这个时候我们翻代码找了一下,发现methodCache确实是一个Map,定义如下:

image.png

大家可以看到,在上边的代码中,缓存methodCache的key是一个MethodCacheKey对象,而value则是一个List集合,其实就是专门放拦截器使用的,其实这个value就是我们要获取的拦截器链

既然现在已经确定缓存methodCache是一个Map了,那么再从Map中获取拦截器链时,一定会使用到key,那么这个key是怎么构造出来的呢?说白了就是MethodCacheKey对象是怎么构造出来的呢?

这个时候我们来看下MethodCacheKey的构造方法,如下图:

image.png

通过上边的代码,大家可以看到,MethodCacheKey的构造方法其实很简单,其实就是将入参method本身和method的hashCode值分别赋值给了自己内部的成员变量method和hashCode了。

好了,现在搞清楚了MethodCacheKey构造方法和methodCache的数据结构后,我们再回到主线上来,

通过上边的代码,可以看到,其实就是先通过传进来的method构建出来一个缓存key,然后使用这个缓存key从methodCache中获取拦截器链cached,methodCache本质就是一个Map。

如果缓存中存在拦截器链的话,即cached不为null,就直接将拦截器链cached作为结果返回。

而如果缓存中不存在拦截器链的话,即cached为null,那么此时就调用AdvisorChainFactory的getInterceptorsAndDynamicInterceptionAdvice()方法获取拦截器链,并且将最后获取的拦截器链put到缓存methodCache中,这样当下一次获取拦截器链时,就可以直接走缓存了。

说白了这里就是使用缓存做了优化罢了,获取拦截器链的核心逻辑,其实是在AdvisorChainFactory的getInterceptorsAndDynamicInterceptionAdvice()方法中的。

getInterceptorsAndDynamicInterceptionAdvice

config是ProxyFactory

method是我们要调用的原始方法

targetcalss是我们的bean的class

```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;
            //使用当前调用的方法和advisor匹配
            if (mm instanceof IntroductionAwareMethodMatcher) {
                if (hasIntroductions == null) {
                        hasIntroductions = 
                            hasMatchingIntroductions(advisors, actualClass);
                }
                match = ((IntroductionAwareMethodMatcher) mm)
                            .matches(method, actualClass, hasIntroductions);
            }else {
                match = mm.matches(method, actualClass);
            }
            //如果匹配那么就构造1个MethodInterceptor 加入拦截器链
            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;

} ```

首先从config中获取到了增强advisors,前边我们也分析过了,这个config其实就是最开始时构造的ProxyFactory对象,当时在构造ProxyFactory对象时,就为ProxyFactory设置了可用的增强advisors。

Advisor[] advisors = config.getAdvisors()

说白了就是从ProxyFactory中获取当时设置的可用的增强advisors,就是这个意思。

而且大家要知道的是这个增强advisors,是当时分别通过类级别和方法级别匹配出来的。

并且需要注意的是:这个增强advisors是目标类维度对应的增强,为什么这样说呢?

因为当时为目标类匹配增强的时候,Spring的处理逻辑是:

只要目标类中任意一个方法匹配上增强的切点表达式。

那么就会直接将这个增强放入到目标类对应的“合格增强”集合中。

那接下来该做什么处理了呢?

我们来分析一下,现在我们已经获取到了目标类在类级别对应的增强advisors,其实就是当时设置在ProxyFactory中的增强advisors。

但是呢,我们在真正执行目标方法时,肯定不能将类级别的增强advisors全部执行一遍吧?

为什么呢?

答案在findAdvisorThatCanApply方法中调用的canApply方法中。

分别在类级别和方法级别进行匹配,首先会调用pc.getClassFilter().matches(targetClass)进行类级别的匹配,说白了就是使用切点表达式和目标类进行匹配,如果在类级别都不满足切点表达式的话,那么就没必要进一步去匹配方法了。

只有当类级别满足切点表达式之后,才会进行方法级别的匹配,此时就会获取目标类中的方法,然后依次判断每个方法是否与切点表达式正常匹配。如果匹配加入advisor集合。

只要目标类中有一个方法可以和切点表达式匹配上,那么就把这个Advisor加入eligiableAdvisors。

只要目标类中有一个方法可以和切点表达式匹配上,那么就把这个Advisor加入eligiableAdvisors。

只要目标类中有一个方法可以和切点表达式匹配上,那么就把这个Advisor加入eligiableAdvisors。

假设A方法可以和切面表达式匹配那么对应的advisor就会加入eligibleAdvisors集合

所以这就要求我们在调用的过程中,需要做精确匹配。

因为通过方法A筛选出来符合条件的advisor对于方法B可能不适用。

所以将类级别的增强advisors全部执行一遍肯定是不合理的,因为有的增强是不适用于当前方法(也就是目标方法)的,所以接下来就要为目标方法匹配出适用的增强,那么具体怎么进行匹配呢,先继续往下看。

接下来看看interceptorList变量和actualClass变量。

interceptorList就是一个拦截器集合,它的大小被设置为了增强advisors的大小,而actualClass代表的则是被调用方法的声明类,声明类是通过getDeclaringClass()方法获取的,在我们这个场景中,这个声明类其实就是我们的代理类。

那么到这里为止,做的事儿无非就是声明了几个变量而已,分别是当前bean适用的增强advisors、拦截器集合interceptorList以及目标类actualClass这三个变量,而目标类actualClass其实就是ProductServiceImpl这个类。

然后是一个for循环,并且这个for循环是对增强advisors做的遍历处理。

在处理的时候有一个if else if else语句,

if条件分别是advisor instanceof PointcutAdvisor和advisor instanceof IntroductionAdvisor.

也就是判断当前增强到底是不是PointcutAdvisor类型和IntroductionAdvisor类型。

看到PointcutAdvisor和IntroductionAdvisor大家有没有觉得眼熟呢?

觉得眼熟就对了,在前边的文章中我们可是分析过的,这个PointcutAdvisor代表的是普通增强,而IntroductionAdvisor代表的是引介增强,引介增强的控制粒度是类级别的,一般不常用。

我们常用的还是控制粒度为方法级别的普通增强,所以接下来我们主要会分析一下普通增强的处理。

然后是if条件,才会正常往下进行处理。

java if (config.isPreFiltered() || pointcutAdvisor.getPointcut() .getClassFilter() .matches(actualClass)) { }

我们可以看到这个if条件有2个条件,只要满足其中一个条件,就可以正常往下进行处理了,其中一个条件就是config.isPreFiltered(),说白了就是看下ProxyFactory中的preFiltered标识是否为true,而这个preFiltered标识通过名字猜测,大概表示的意思是“是否为预过滤”,如果是预过滤,那么就正常往下执行。

其实这个preFiltered标识,当时我们在ProxyFactory构造那节就讲过,这个preFiltered属性通常会被设置为true,所以这个if条件通常是满足的。

那万一这个preFiltered属性为false呢?这个时候该怎么办?

如果preFiltered为false,那么这个时候就要来判断第二个条件

java pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)

这个条件,那这行代码是什么意思呢?

首先这个pointcutAdvisor代表的是增强,然后从这个增强pointcutAdvisor中获取到了一个切点Pointcut。

接着从切点Pointcut中获取到了一个ClassFilter,而这个ClassFilter看名字是类过滤器的意思,最后通过ClassFilter的matches()方法完成了判断。

而且在调用ClassFilter的matches()方法时,我们注意到将目标类actualClass作为入参传递到了matches()方法中,其实到这里,我们大概可以判断出这行代码的作用了,其实就是用类过滤器在类级别判断方法所在的目标类actualClass是否和当前增强pointcutAdvisor的切面表达式匹配

说白了就是看一下目标类actualClass,也就是代理类,是否满足增强中配置的切点表达式,如果满足的话,再进行进一步的处理,就是这个意思。

java MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();

其实和刚才获取类过滤器ClassFilter一样,通过这行代码获取到了当前增强的方法匹配器MethodMatcher。

并且将方法匹配器MethodMatcher赋值给了mm变量,那么这个方法匹配器MethodMatcher有啥用呢?

其实我们大胆猜测一下,这个方法匹配器MethodMatcher,应该是用来判断当前增强是否匹配目标方法的。

这里会根据方法匹配器mm的类型不同,做不同的处理,但是核心都是一样的,最后都会调用方法匹配器mm的matches()方法完成判断,而这个matches()方法的其中一个入参就是目标方法method。

说白了就是在方法级别,来判断一下目标方法和增强中的切点表达式是否匹配。

也就是说这里匹配的时候,会先在类级别判断是否匹配,如果类级别匹配成功,那么就在方法级别进一步判断是否匹配,这样的套路,大家是不是感觉在哪里见到过?但又一下子想不起来?

其实啊,大家有这种感觉是正常的,因为我们之前真的分析过“类似”的源码哦,那就是我们之前在分析为目标类匹配切面的时候。接下来如果MethodMatcher是IntroductionAwareMethodMatcher类型的话,就强转一下,最后调用IntroductionAwareMethodMatcher的matches()方法完成了方法级别的判断。

java if (mm instanceof IntroductionAwareMethodMatcher) { if (hasIntroductions == null) { hasIntroductions = hasMatchingIntroductions(advisors, actualClass); } match = ((IntroductionAwareMethodMatcher) mm) .matches(method, actualClass, hasIntroductions); }else { match = mm.matches(method, actualClass); } }

方法级别匹配时,最后都是通过aspectj包下的matchesExactlyMethod()方法完成了方法级别的精确匹配,说白了就是分别对方法参数、方法名称、方法返回值几个维度进行匹配,这个我们之前都分析过相应的源码,大家忘记的话,可以回头在复习一下。

当match为true的时候,首先会执行

java registry.getInterceptors(advisor)

这行代码来获取增强advisor中的拦截器,并将获取到的拦截器赋值给interceptors数组,最终将interceptors数组添加到拦截器集合interceptorList中。

说白了就是先找到适用于当前方法对应的增强advisor,然后再获取到增强advisor对应的拦截器interceptors,最终将拦截器interceptors收集起来,也就是最后给放到了拦截器集合interceptorList中。

刚才我们分析的是普通增强的处理,而这里则是引介增强和其他类型增强的处理,过程都差不太多,比如引介增强这里在目标类级别进行了判断,如果匹配成功的话,就将增强对应的拦截器放入到拦截器集合interceptorList中。

最后当for循环执行完毕时,也就是目标类级别对应的所有增强advisor都处理完毕了,那么就会将拦截器集合interceptorList作为结果进行返回。

需要注意的是,最后返回的这个拦截器集合interceptorList是目标方法级别对应要执行的增强,也就是在执行目标方法时,这个拦截器集合interceptorList中的拦截器都是需要执行的!

接着就会将返回的拦截器集合,也就是拦截器链放入到缓存中,这样可以便于下一次直接从缓存中获取拦截器链,最后将拦截器链返回。最后在JdkDynamicAopProxy的invoke()方法中,就可以获取到拦截器链chain。

到这里为止,就成功获取到目标方法适用的拦截器链了,当目标方法执行的时候,拦截器链chain中的拦截器都需要被执行!

那么最后大家来思考一个问题,那就是之前为目标类匹配增强时,曾经在类级别和方法级别做过匹配,但是这里在为目标方法匹配增强时,又在类级别和方法级别进行了匹配,是不是感觉有点重复处理了?

其实是这样的,主要是处理维度不同,当时为目标类匹配增强是类维度的匹配,主要是为目标类匹配可以适用的增强,即目标类中有任何一个方法与增强匹配成功,那么就说明这个增强适用于目标类,此时会把目标类维度适用的增强收集起来,此时的对应关系就是目标类对应了一堆增强,这些增强会被设置到ProxyFactory中,在真正执行目标方法时会使用。

而在执行目标方法时,虽然此时可以获取到这个目标类对应的一堆增强,但无法知道某一个方法对应的增强都有哪些,因为总不能你调用一个方法时,就把这个类对应的所有增强都执行一遍吧?这样显然是不合理的,所以此时需要遍历这些增强,进一步匹配出目标方法适用的增强!所以此时的匹配是目标方法维度的匹配。

匹配成功的增强Advisor是如何被处理的?

java MethodInterceptor[] interceptors = registry.getInterceptors(advisor);

这行代码来获取增强advisor中的拦截器,并将获取到的拦截器赋值给interceptors数组,最终将interceptors数组添加到拦截器集合interceptorList中。

但是1个增强器返回的是1个数组?

是的,因为1个advisor包含多个advice,1个advice对应1个MethodInterceptor。

java @Override public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException { List<MethodInterceptor> interceptors = new ArrayList<>(3); //advice是什么东西? Advice advice = advisor.getAdvice(); if (advice instanceof MethodInterceptor) { interceptors.add((MethodInterceptor) advice); } 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]); }

首先通过getAdvice()方法获取了advice属性罢了,看起来像是一个“普通”的get()方法。

嗯?真的是这样吗?这个getAdvice()方法真的只是一个“普通”的get()方法吗?

先看看advisor是什么?

当时构建Advisor时,使用的是InstantiationModelAwarePointcutAdvisorImpl类的实例

java for (Method method : getAdvisorMethods(aspectClass)) { //构建InstantiationModelAwarePointcutAdvisorImpl实例 Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName); if (advisor != null) { advisors.add(advisor); } }

```java public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,int declarationOrderInAspect, String aspectName) {

validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());

AspectJExpressionPointcut expressionPointcut 
        = getPointcut(candidateAdviceMethod, 
            aspectInstanceFactory .getAspectMetadata().getAspectClass());
if (expressionPointcut == null) {
    return null;
}
//构建InstantiationModelAwarePointcutAdvisorImpl实例
return new InstantiationModelAwarePointcutAdvisorImpl
        (expressionPointcut, candidateAdviceMethod,
              this, aspectInstanceFactory, declarationOrderInAspect, aspectName);

} ```

我们可以看到,在构建Advisor时,本质就是构建了一个InstantiationModelAwarePointcutAdvisorImpl类的实例,并且在构建的时候,构造方法的入参中传递了一些非常重要的参数,其中就包括切面中声明的增强方法aspectJAdviceMethod。

接下来分析这一行代码:根据aspectJ注解类型构建不同的Advice

java Advice advice = advisor.getAdvice();

InstantiationModelAwarePointcutAdvisorImpl类的getAdvice()方法的代码如下:

```java @Override public synchronized Advice getAdvice() { if (this.instantiatedAdvice == null) { this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut); } return this.instantiatedAdvice; }

private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) { Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut, this.aspectInstanceFactory, this.declarationOrder, this.aspectName); return (advice != null ? advice : EMPTY_ADVICE); } ```

我们可以看到这个getAdvice()方法明显不是“普通”的get()方法啊,它里边是有一些逻辑的!

所以平时分析源码时,我们还是眼见为实,有时候看到的不一定就是真实的哦。

此时我们发现上边的代码,其实是在初始化一个Advice实例,可以看到,在进入这个getAdvice()方法的时候,首先会看一下instantiatedAdvice是否为null,如果为null的话,那么表示是第一次调用这个getAdvice()方法,此时就会通过instantiateAdvice()方法创建一个Advice实例出来,接着将这个Advice实例返回。

调用一个叫getAdvice()方法来获取Advice的,同时将自己内部的aspectJAdviceMethod属性作为入参传递了进去,通过前边的分析,我们知道这个aspectJAdviceMethod其实就是切面中声明的增强方法。

接下来我们要继续往下深入了,其实就是来看下上边的getAdvice()方法了。

此时我们点进去后,可以发现getAdvice()方法的代码

```java public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {

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

validate(candidateAspectClass);
//获取@Around, @Before,@After, @AfterReturning, @AfterThrowing注解
AspectJAnnotation<?> aspectJAnnotation 
                        =AbstractAspectJAdvisorFactory
                                        .findAspectJAnnotationOnMethod
                                                        (candidateAdviceMethod);
//获取不到就返回
if (aspectJAnnotation == null) {
    return null;
}
//判断是否
if (!isAspect(candidateAspectClass)) {
    throw new AopConfigException("Advice must be declared inside an aspect type: " +
                    "Offending method '" + candidateAdviceMethod + "' in class [" +
                    candidateAspectClass.getName() + "]");
}

AbstractAspectJAdvice springAdvice;

//根据@Around, @Before,@After, @AfterReturning, @AfterThrowing注解转换为不同的Advice
switch (aspectJAnnotation.getAnnotationType()) {
    case AtPointcut:
        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();
}

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

return springAdvice;

} ```

java AspectJAnnotation<?> aspectJAnnotation =AbstractAspectJAdvisorFactory .findAspectJAnnotationOnMethod(candidateAdviceMethod);

调用了findAspectJAnnotationOnMethod()方法,而这个方法我们也是比较熟悉的,它其实就是在指定的方法中寻找AspectJ的注解。

然后根据扫描出来的@Around, @Before,@After, @AfterReturning, @AfterThrowing注解类型,会创建不同实现的Advice实例。

假如此时扫描到的注解是@Before注解,那么annotationType的值就是AtBefore,那么接着就会执行

java springAdvice = new AspectJMethodBeforeAdvice (candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);

```java public AspectJMethodBeforeAdvice(Method aspectJBeforeAdviceMethod,AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) { super(aspectJBeforeAdviceMethod, pointcut, aif); }

```

java public AbstractAspectJAdvice(Method aspectJAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aspectInstanceFactory) { Assert.notNull(aspectJAdviceMethod, "Advice method must not be null"); this.declaringClass = aspectJAdviceMethod.getDeclaringClass(); this.methodName = aspectJAdviceMethod.getName(); this.parameterTypes = aspectJAdviceMethod.getParameterTypes(); this.aspectJAdviceMethod = aspectJAdviceMethod; this.pointcut = pointcut; this.aspectInstanceFactory = aspectInstanceFactory; }

我们可以看到,其实AspectJMethodBeforeAdvice类的构造方法没啥逻辑,主要就是将这些核心属性又传递给了父类AbstractAspectJAdvice的构造方法,而父类拿到这些核心属性后,就将这些核心属性赋值给了自己的成员变量,而这里边最最重要的属性,其实就是这个增强方法aspectJAdviceMethod了。

那这个增强方法aspectJAdviceMethod到底有什么用呢?

但是我们可以先大胆猜测一波,在执行目标方法时,这些增强方法肯定也会执行,那么具体怎么执行呢?

我们会发现这个增强方法aspectJAdviceMethod其实是Method类型,而这个Method是反射包下的一个类,所以执行增强方法时,会不会是通过反射调用的?

说白了就是通过aspectJAdviceMethod.invoke()这样的形式来调用增强方法,但是这个呢,目前只是我们的一个猜测,至于最后是不是这样玩儿的,我们带着这个疑问分析下去就会知道了!

AtAfter的处理也是一样的套路,就是将增强方法aspectJBeforeAdviceMethod等关键属性传递给父类,然后父类进行初始化。

但是我们也发现了不一样的地方,那就是这个AspectJAfterAdvice类中多出来一个invoke()方法,虽然目前我们不知道这个invoke()方法是干嘛的,但给我们的感觉是这个invoke()方法是非常重要的。

```java public AspectJAfterAdvice(Method aspectJBeforeAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) { super(aspectJBeforeAdviceMethod, pointcut, aif); }

@Override public Object invoke(MethodInvocation mi) throws Throwable { try { return mi.proceed(); } finally { invokeAdviceMethod(getJoinPointMatch(), null, null); } } ```

此时我们还发现invoke()方法上有一个@Override的注解,然后方法最左边还有一个接口的小图标image.png,那么很明显这个invoke()方法是从某一个接口继承过来的,那么到底是哪个接口呢?

其实实现的是MethodInterceptor接口的invoke()方法,从MethodInterceptor接口的名字上看,是方法拦截器的意思,那它和我们这几天分析的拦截器链有没有什么关系的?

其实拦截器就是MethodInterceptor接口类型的一个实例罢了,MethodInterceptor其实就是拦截器,而拦截器链就是一个一个的MethodInterceptor,就是这个意思,非常简单。

TransactionInterceptor也实现了 MethodInterceptor接口。

就是根据切面中增强方法上的注解不同,创建不同的Advice实例出来,并将创建出来的Advice实例赋值给springAdvice变量。

java springAdvice.setAspectName(aspectName); springAdvice.setDeclarationOrder(declarationOrder); String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod); if (argNames != null) { springAdvice.setArgumentNamesFromStringArray(argNames); } springAdvice.calculateArgumentBindings();

总结一下就是从Advisor获取方法,拿到方法上的增强注解。根据不同的增强注解,创建不同的Advice,Advice有的实现了MethodInterceptor接口,有的没有实现MethodInterceptor接口。Advice中封装了原始的切面方法aspectJAdviceMethod。

实现了MethodInterceptor接口的advice

md AspectJAroundAdvice extends AbstractAspectJAdvice implements MethodInterceptor, Serializable AspectJAfterAdvice extends AbstractAspectJAdvice implements MethodInterceptor, AfterAdvice, Serializable AspectJAfterThrowingAdvice extends AbstractAspectJAdvice implements MethodInterceptor, AfterAdvice, Serializable

没有实现MethodInterceptor接口的advice

md AspectJAfterReturningAdvice extends AbstractAspectJAdvice implements AfterReturningAdvice, AfterAdvice, Serializable AspectJMethodBeforeAdvice extends AbstractAspectJAdvice implements MethodBeforeAdvice, Serializable

花了这么一番功夫构建的advice到底有什么用呢?

java public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException { List<MethodInterceptor> interceptors = new ArrayList<>(3); Advice advice = advisor.getAdvice(); //如果是MethodInterceptor 直接添加即可 if (advice instanceof MethodInterceptor) { interceptors.add((MethodInterceptor) advice); } //否则就调用适配器 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 Advice advice = advisor.getAdvice();

简单回顾下都干了啥,首先advisor其实就是InstantiationModelAwarePointcutAdvisorImpl类的一个实例,当时构建这个InstantiationModelAwarePointcutAdvisorImpl实例时,将增强方法作为参数给传递了进去,所以这个advisor中包含了切面中定义的增强方法,比如afterReturning()增强方法。

接着分析下getInterceptors()方法剩下的代码。

if (advice instanceof MethodInterceptor) {
    interceptors.add((MethodInterceptor) advice);
}
for (AdvisorAdapter adapter : this.adapters) {
    if (adapter.supportsAdvice(advice)) {
        interceptors.add(adapter.getInterceptor(advisor));
    }
}
if (interceptors.isEmpty()) {
    throw new UnknownAdviceTypeException(advisor.getAdvice());
}

如果这个advice是MethodInterceptor接口实现类的话,那么就直接将advice强转为MethodInterceptor类型并放入到拦截器interceptors中。

在分析advice的构建流程时,发现有一部分增强方法构建出来的Advice实例其实是MethodInterceptor接口的实现类,比如AspectJAfterAdvice。所以像AspectJAfterAdvice就会被直接放到拦截器interceptors中

说白了就是如果advice是MethodInterceptor的实现类,那么就将advice强转后直接放入到拦截器interceptors中

那么上节构建的advice中,都有哪些advice实现了MethodInterceptor接口,而又有哪些没有实现MethodInterceptor接口呢?

AspectJAfterAdvice、AspectJAroundAdvice、AspectJAfterThrowingAdvice都实现了MethodInterceptor接口,因此这三种Advice本身就是拦截器,而这三种Advice分别对应了@After、@Around和@AfterThrowing这三种增强。所以这三种增强可以直接添加到拦截器集合interceptors中

但是我们知道AspectJ中一共是有五种增强的,那剩下没有实现MethodInterceptor接口的增强又该怎么处理呢?

这里我们先来猜测一波,我们知道getInterceptors()方法中最终要返回的是拦截器集合interceptors,而interceptors的定义则是MethodInterceptor类型的List集合。

那么此时我们就需要将AspectJ中的五种增强都放到interceptors中返回,但是其中有两种增强,因为没有实现MethodInterceptor接口,所以不能直接放入到interceptors中,那这个时候怎么办呢?

其实很简单啊,我们将没有实现MethodInterceptor接口的增强包装一下不就得了?说白了就是将它们包装为MethodInterceptor类型的实例。

目前为止呢,这个只是我们的猜测,那到底是不是这样处理的呢?我们继续往下分析就知道了。

其实呢,对于没有实现MethodInterceptor接口的增强,会有单独的逻辑进行处理,我们继续往下看,就会看到这样一块代码。

java for (AdvisorAdapter adapter : this.adapters) { if (adapter.supportsAdvice(advice)) { interceptors.add(adapter.getInterceptor(advisor)); } }

java public DefaultAdvisorAdapterRegistry() { registerAdvisorAdapter(new MethodBeforeAdviceAdapter()); registerAdvisorAdapter(new AfterReturningAdviceAdapter()); registerAdvisorAdapter(new ThrowsAdviceAdapter()); }

这个adapters其实就是一个List集合,默认大小为3,是通过构造方法进行初始化的。 而构造方法通过调用registerAdvisorAdapter()方法,向adapters中添加了3个Adapter,分别是MethodBeforeAdviceAdapter、AfterReturningAdviceAdapter和ThrowsAdviceAdapter,看名字就是适配器的意思。

非MethodInterceptor类型的Advice是怎么包装为拦截器的?

好了,现在我们知道了adapters中,其实就是MethodBeforeAdviceAdapter、AfterReturningAdviceAdapter和ThrowsAdviceAdapter这三个Adapter,那么我们回到主线,继续往下分析,我们现在要分析的代码如下:

遍历adapters中的三个Adapter,然后会调用Adapter的supportsAdvice()方法,通过名字来猜测,这个supportsAdvice()方法应该是来判断是否支持增强的。

那现在我们已经知道了adapters中的三个Adapter都是谁了,那么我们就干脆来看下这三个Adapter中的supportsAdvice()方法都是怎么实现的吧,此时代码如下:

image.png

这三个Adapter的supportsAdvice()方法,主要是来看一下这个advice是不是指定的类型,比如MethodBeforeAdviceAdapter会看一下advice是不是MethodBeforeAdvice类型,而AfterReturningAdviceAdapter则是看一下advice是不是AfterReturningAdvice类型。

那剩下的这两种增强,也就是@Before和@AfterReturning,到底是哪种类型呢?

这个其实也简单,我们来看下这两种增强的类继承关系就知道了,首先我们来看下@Before增强的类继承图,也就是AspectJMethodBeforeAdvice的类继承图,如下:

image.png

当advice为AspectJMethodBeforeAdvice时,由于AspectJMethodBeforeAdvice实现了MethodBeforeAdvice接口,所以此时适配器MethodBeforeAdviceAdapter的supportsAdvice()方法就会返回true!

当advice为AspectJAfterReturningAdvice时,由于AspectJAfterReturningAdvice实现了AfterReturningAdvice接口,所以适配器AfterReturningAdviceAdapter的supportsAdvice()方法会返回true!

一旦supportsAdvice()方法返回true,那么就会执行下边这行代码:

java interceptors.add(adapter.getInterceptor(advisor));

这里其实就是会调用适配器Adapter的getInterceptor()方法。

那现在我们将supportsAdvice()方法和getInterceptor()方法结合起来,来看下这块for循环的代码到底是啥意思。

当advice为AspectJMethodBeforeAdvice时,遍历到适配器MethodBeforeAdviceAdapter时,supportsAdvice()方法会返回true,那么这个时候就调用适配器MethodBeforeAdviceAdapter的getInterceptor()方法开始处理AspectJMethodBeforeAdvice了,最后将处理结果放到拦截器interceptors中。

而当advice为AspectJAfterReturningAdvice时,此时遍历到适配器AfterReturningAdviceAdapter,然后发现supportsAdvice()方法的执行结果为true,那么就会调用适配器AfterReturningAdviceAdapter的getInterceptor()方法来处理AspectJAfterReturningAdvice,最后将处理结果放入拦截器interceptors中。

同学们,分析到这里,大家发现了吗?

其实这个for循环遍历适配器的代码,无非就是为了让合适的适配器来处理这个advice,比如适配器MethodBeforeAdviceAdapter就是专门来处理AspectJMethodBeforeAdvice的;而适配器AfterReturningAdviceAdapter就是专门来处理AspectJAfterReturningAdvice的。

```java @Override public MethodInterceptor getInterceptor(Advisor advisor) { MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice(); return new MethodBeforeAdviceInterceptor(advice); }

public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) { Assert.notNull(advice, "Advice must not be null"); this.advice = advice; } ```

```java public MethodInterceptor getInterceptor(Advisor advisor) { AfterReturningAdvice advice = (AfterReturningAdvice) advisor.getAdvice(); return new AfterReturningAdviceInterceptor(advice); }

public AfterReturningAdviceInterceptor(AfterReturningAdvice advice) { Assert.notNull(advice, "Advice must not be null"); this.advice = advice; } ```

说白了,这里无非就是将一个advice包装为了一个拦截器MethodInterceptor。

将advice包装为拦截器后,接着就将拦截器放入了拦截器集合interceptors中,最后会将拦截器集合interceptors作为结果返回。

那这里我们思考一个问题:那就是Advice和拦截器到底有什么关系?

其实很简单,不过首先我们需要知道一个前提,那就是拦截器说白了就是MethodInterceptor接口的实现类

知道这个前提后,我们接着来分析下,其实Advice可以分为有两大类,一类是实现了MethodInterceptor接口的,另外一类是没有实现MethodInterceptor接口的。

对于实现了MethodInterceptor接口的这些Advice来说,Advice本身就是一个拦截器,此时Advice和拦截器就是同一个东西。

而对于没有实现MethodInterceptor接口的Advice来说,Advice和拦截器MethodInterceptor没有直接关系,但是Spring会将Advice作为一个属性,给封装到MethodInterceptor的实现类中,所以此时Advice其实就是拦截器中的一个属性。

创建ReflectiveMethodInvocation

java if (chain.isEmpty()) { Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args); retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse); }else { //创建1个ReflectiveMethodInvocation //注意参数chain MethodInvocation invocation = new ReflectiveMethodInvocation (proxy, target, method, args, targetClass, chain); //这个是一个chain 触发责任链 retVal = invocation.proceed(); }

如果拦截器链为空,那么说明没有匹配上任何增强方法。

会直接通过反射调用了目标方法!非常的简单,关键代码其实就一行,那就是method.invoke(target, args)。

java @Nullable public static Object invokeJoinpointUsingReflection(@Nullable Object target, Method method, Object[] args)throws Throwable { try { ReflectionUtils.makeAccessible(method); return method.invoke(target, args); }catch (InvocationTargetException ex) { throw ex.getTargetException(); } catch (IllegalArgumentException ex) { throw new AopInvocationException("); } catch (IllegalAccessException ex) { throw new AopInvocationException(); } }

那么这个时候就代表,在执行目标方法的时候,不需要执行任何增强逻辑,那么这个时候可不就是直接执行目标方法就完事儿了蛮,所以这里就直接通过反射来调用目标方法了,就是这个意思。

java //创建1个ReflectiveMethodInvocation //注意参数chain MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain); //这个是一个chain 触发责任链 retVal = invocation.proceed();

ReflectiveMethodInvocation#proceed

如果拦截器链不为空需要构建一个ReflectiveMethodInvocation对象。

构造方法的入参有目标对象target、目标方法method、参数args以及拦截器链chain等。

对应的构造方法代码如下:

java protected ReflectiveMethodInvocation(Object proxy, @Nullable Object target, Method method, @Nullable Object[] arguments,@Nullable Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers) { this.proxy = proxy; this.target = target; this.targetClass = targetClass; this.method = BridgeMethodResolver.findBridgedMethod(method); this.arguments = AopProxyUtils.adaptArgumentsIfNecessary(method, arguments); this.interceptorsAndDynamicMethodMatchers = interceptorsAndDynamicMethodMatchers; }

我们可以看到,其实上边这个构造方法非常简单,没啥特殊的,主要就是初始化目标对象target、目标方法method、拦截器链interceptorsAndDynamicMethodMatchers等属性。

拦截器链执行的关键,还是下一行代码

java retVal = invocation.proceed();

```java @Override @Nullable public Object proceed() throws Throwable { // 初始currentInterceptorIndex为-1,每调用一次proceed就把currentInterceptorIndex+1 // 假如有2个前置before增强方法 会不会有问题? // 不会,原因是第一次执行第一个before增强方法时 ++this.currentInterceptorIndex=0 // 调用完以后 if (this.currentInterceptorIndex ==this.interceptorsAndDynamicMethodMatchers.size() - 1) { // 当调用次数 = 拦截器个数时 // 1. 触发当前method方法 return invokeJoinpoint(); } Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers .get(++this.currentInterceptorIndex); if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) { 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 {
    return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}

} ```

可以看到,这里有一个布尔表达式,而布尔表达式中的interceptorsAndDynamicMethodMatchers其实就是刚才的拦截器链chain。

this.interceptorsAndDynamicMethodMatchers.size() - 1

这行代码的结果其实就是拦截器链中最后一个拦截器的下标。

比如拦截器链中一共有5个拦截器的话,那么这行代码的结果就是4

那么布尔表达式中的另外一个变量currentInterceptorIndex又是多少呢?

currentInterceptorIndex默认为-1,那也就是说刚开始进来的时候,这个布尔表达式的结果为false,是不满足的。

那这个条件什么时候能满足呢?

其实就是当currentInterceptorIndex的值为拦截器链最后一个拦截器的下标时,才会满足,此时就会执行invokeJoinpoint()这行代码。

那么invokeJoinpoint()这行代码究竟是干嘛的呢?

java protected Object invokeJoinpoint() throws Throwable { return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments); }

```java @Nullable public static Object invokeJoinpointUsingReflection(@Nullable Object target, Method method, Object[] args) throws Throwable {

try {
    ReflectionUtils.makeAccessible(method);
    return method.invoke(target, args);
}catch (InvocationTargetException ex) {
    throw ex.getTargetException();
}
catch (IllegalArgumentException ex) {
    throw new AopInvocationException(");
}
catch (IllegalAccessException ex) {
    throw new AopInvocationException();
}

} ```

我们可以看到,其实这里核心只有一行代码,那就是method.invoke(target, args)。说白了就是通过反射来调用目标方法!需要满足的条件就是currentInterceptorIndex需要等于拦截器链的最后一个下标,并且这个currentInterceptorIndex默认为-1。

java Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);

在调用拦截器链时会修改currentInterceptorIndex的值,这里就会对currentInterceptorIndex进行++操作,并且需要注意的是这个++是在currentInterceptorIndex变量前边的,所以会先对currentInterceptorIndex执行++操作,也就是currentInterceptorIndex会由-1变为0,然后再使用这个currentInterceptorIndex变量。

使用的时候也很简单,这里直接将currentInterceptorIndex作为拦截器链的下标,来从拦截器链interceptorsAndDynamicMethodMatchers中获取拦截器,此时拦截器下标currentInterceptorIndex为0,所以获取的是第一个拦截器。

由于这里是++操作,所以如果是第二次来执行上边这行代码,那么currentInterceptorIndex就会由0变为1,这个时候就会获取拦截器链中第二个拦截器了。

```java //获取拦截器 Object interceptorOrInterceptionAdvice =this.interceptorsAndDynamicMethodMatchers .get(++this.currentInterceptorIndex); //判断类型 if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) { 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 {
    return proceed();
}

}else { // 2. 普通拦截器,直接触发拦截器invoke方法 return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this); } ```

这里根据拦截器的类型分开进行了处理,第一种是将刚才获取的拦截器强转为interceptorOrInterceptionAdvice类型,第二种是将拦截器强转为MethodInterceptor类型。

很明显就是两种不同的处理,那么这里会走哪种呢?

其实根据我们一路分析过来的经验来说,应该会走第二种,也就是会将拦截器强转为MethodInterceptor类型。

那有同学可能会问了,走第一种不行吗?为啥要走第二种?

其实很简单,因为通过前边几篇文章的分析,我们知道aspectJ的五种增强都是MethodInterceptor接口的实现类,所以强转为MethodInterceptor是最符合逻辑的,其实事实也确实走的是第二种。

java //this是ReflectiveMethodInvocation return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);

很明显调用的是拦截器的invoke()方法,就是之前我们分析Advice实现类时,感觉很重要的那个方法!

我们知道aspectJ一共有五种增强,而这五种增强也都实现了MethodInterceptor接口的invoke()方法,当然其中有两种增强是后来包装为MethodInterceptor类型的,但是最后这五种增强确实都实现了invoke()方法。

那这个时候就会按照拦截器链上的顺序,来执行拦截器中的逻辑了。

那这五种增强对应的拦截器中都有哪些逻辑呢?

执行拦截器链时又是怎么保证Before增强一定在After增强之前执行呢?

通过上边的代码,我们可以看到,这里直接调用了拦截器的invoke()方法,并且将this,说白了就是将ReflectiveMethodInvocation自己作为入参传递到了拦截器中,那么接下来就要来执行拦截器中的逻辑了。

那现在问题来了,我们知道aspectJ一共有五种拦截器,上边这行代码执行的是哪个拦截器呢?

并且我们都知道,对于AOP的增强来说,Before增强通常都是先开始执行的,那么上边即将执行的拦截器是不是Before增强对应的拦截器呢?

image.png

我们可以看到,此时拦截器链中有6个拦截器,此时有同学就郁闷了,aspectJ的增强只有5种啊,这里为啥有6个呢?

是这样的,其实第一个拦截器ExposeInvocationInterceptor,它主要是用于暴露拦截器链到ThreadLocal中,这样同一个线程下就可以来共享拦截器链了,不过这个ExposeInvocationInterceptor拦截器不是我们这里的重点,大家有个印象就可以了,我们继续往下看。

此时我们发现,在拦截器链中,After拦截器AspectJAfterAdvice竟然在Before拦截器MethodBeforeAdviceInterceptor的前面!如下图:

image.png

这就奇怪了,按照AOP的规则,Before增强肯定是在After增强前执行的呀,为啥拦截器链中的顺序,Before增强竟然排到After增强的后边了?真是奇了怪了

同学不要着急,是这样的,拦截器链的执行顺序,其实并不是简单的将拦截器链进行for循环遍历,而是人家有专门的一套玩儿法!

那这个拦截器链到底是怎么来玩儿的呢?

我们接着往下分析,大家慢慢就都明白了。

我们回到主线上来,还记得我们这节主要是干嘛的吗?

哈哈,其实就是要来分析拦截器内部的代码,所以我们接下来,就来看下拦截器中的代码呗。

其实呢,通过上节的分析,我们知道拦截器的下标currentInterceptorIndex默认值是-1,再执行过++currentInterceptorIndex操作后,值会由-1修改为0。

所以接下来的操作,就会来获取拦截器链中下标0对应的拦截器,也就是第一个拦截器ExposeInvocationInterceptor,ExposeInvocationInterceptor也实现了MethodInterceptor。

所以我们看invoke方法。

而这个ExposeInvocationInterceptor拦截器的代码如下:

java private static final ThreadLocal<MethodInvocation> invocation = new NamedThreadLocal<>("Current AOP method invocation"); //mi 是 我们创建的ReflectiveMethodInvocation @Override public Object invoke(MethodInvocation mi) throws Throwable { MethodInvocation oldInvocation = invocation.get(); invocation.set(mi); try { return mi.proceed(); } finally { invocation.set(oldInvocation); } }

我们知道这个invoke()方法的入参mi,其实就是ReflectiveMethodInvocation实例,而ReflectiveMethodInvocation中是包含了拦截器链的。看这块代码的话非常简单,就是将mi变量放入了ThreadLocal中,但它真正想要做的,其实是想将拦截器链放入到ThreadLocal中,这样同一个线程,就可以通过ThreadLocal来共享拦截器链了。

并且我们可以看到,将mi变量放入ThreadLocal之后,还调用了非常关键的一行代码,那就是mi.proceed(),我们知道这个mi变量其实就是ReflectiveMethodInvocation,那也就是说,现在需要调用ReflectiveMethodInvocation的proceed()方法了,也就是这块代码:

```java @Override @Nullable public Object proceed() throws Throwable { // 初始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) {

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 {
    return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}

} ```

我们知道,其实调用拦截器的入口就是ReflectiveMethodInvocation的proceed()方法。

但在这个ExposeInvocationInterceptor拦截器中,竟然又调用了ReflectiveMethodInvocation的proceed()方法,相当于又回到了调用拦截器的入口,而这样其实就达到了递归调用的效果

那么这次递归调用proceed()方法,又有什么特殊之处呢?

其实是这样的,之前在执行这个proceed()方法时,拦截器链下标currentInterceptorIndex的值,已经由默认值-1累加为0了,而区别就在于执行下边这行代码:

java Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);

在这次递归调用时,currentInterceptorIndex的值已经变为0了,那么此时执行到++操作时,下标currentInterceptorIndex的值就会再次进行++操作,也就是会由0变为1。

那这个时候就简单了,由于此时拦截器链下标currentInterceptorIndex为1。

所以此时,就会获取并执行拦截器链中下标为1的拦截器了。那拦截器链中下标为1的拦截器是哪个呢?

image.png

通过上图,我们可以看到,拦截器链中下标为1的拦截器,其实就是AspectJAfterThrowingAdvice了,也就是说下一个要调用的拦截器,其实就是AspectJAfterThrowingAdvice。

image.png

通过上图,我们可以看到,第一个调用的拦截器是ExposeInvocationInterceptor,这个ExposeInvocationInterceptor拦截器,会先将拦截器链暴露到ThreadLocal中。

然后会递归调用ReflectiveMethodInvocation的proceed()方法,那么此时下标index就会执行++操作,从而下标index会由0变为1,这个时候,就会获取并执行拦截器链中下标为1的拦截器了,也就是拦截器AspectJAfterThrowingAdvice。

AfterThrowing增强:发生异常才会执行

我们知道,接下来就要来执行AspectJAfterThrowingAdvice拦截器了,那我们就直接来看下AspectJAfterThrowingAdvice的代码

java @Override public Object invoke(MethodInvocation mi) throws Throwable { try { //放行 return mi.proceed(); }catch (Throwable ex) { //判断ex是否是Object类型 if (shouldInvokeOnThrowing(ex)) { //有异常在执行 invokeAdviceMethod(getJoinPointMatch(), null, ex); } throw ex; } }

mi.proceed()这行代码,其实就是用来递归调用ReflectiveMethodInvocation的proceed()方法的,说白了就是用来执行拦截器链中的下一个拦截器的。

在 AspectJ 语义中,只有在抛出的异常是给定抛出类型的子类型时,才会执行AfterThrowing增强方法。

从这个invokeAdviceMethod()方法的名字上来看,是“执行增强方法”的意思,那它到底是通过什么方式,来执行增强方法的呢?

我们可以进一步来看下invokeAdviceMethod()方法的代码,如下图:

java protected Object invokeAdviceMethod(@Nullable JoinPointMatch jpMatch, @Nullable Object returnValue, @Nullable Throwable ex)throws Throwable { return invokeAdviceMethodWithGivenArgs (argBinding(getJoinPoint(), jpMatch, returnValue, ex)); }

java protected Object invokeAdviceMethodWithGivenArgs(Object[] args) throws Throwable { Object[] actualArgs = args; if (this.aspectJAdviceMethod.getParameterCount() == 0) { actualArgs = null; } try { ReflectionUtils.makeAccessible(this.aspectJAdviceMethod); // 牛逼呀 获取Aspect类的实例 然后调用方法 return this.aspectJAdviceMethod.invoke (this.aspectInstanceFactory.getAspectInstance(), actualArgs); } catch (IllegalArgumentException ex) { throw new AopInvocationException("Mismatch on arguments to advice method [" + this.aspectJAdviceMethod + "]; pointcut expression [" + this.pointcut.getPointcutExpression() + "]", ex); } catch (InvocationTargetException ex) { throw ex.getTargetException(); } }

其实invokeAdviceMethod()方法主要是通过调用invokeAdviceMethodWithGivenArgs()方法来完成功能的。

而invokeAdviceMethodWithGivenArgs()方法中关键的其实就一行代码,那就是this.aspectJAdviceMethod.invoke()这行代码,说白了就是通过反射调用了增强方法,而这个aspectJAdviceMethod大家还记得吗?

其实就是当时构建各种Advice增强时,传入的入参candidateAdviceMethod。

上图中传入的这个入参candidateAdviceMethod,其实就是切面中,定义增强方法对应的method对象

而上边的5种Advice,其实都是AbstractAspectJAdvice的子类,所以最终都会调用父类AbstractAspectJAdvice的构造方法完成属性赋值。

java public AbstractAspectJAdvice(Method aspectJAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aspectInstanceFactory) { Assert.notNull(aspectJAdviceMethod, "Advice method must not be null"); this.declaringClass = aspectJAdviceMethod.getDeclaringClass(); this.methodName = aspectJAdviceMethod.getName(); this.parameterTypes = aspectJAdviceMethod.getParameterTypes(); this.aspectJAdviceMethod = aspectJAdviceMethod; this.pointcut = pointcut; this.aspectInstanceFactory = aspectInstanceFactory; }

这个aspectJAdviceMethod属性,最终会被赋值为切面中定义的增强方法对应的method对象。

对aspectJAdviceMethod属性赋值的过程,其实在之前获取拦截器链的流程中,我们都讲过,如果大家忘记的话,可以回头再看一下获取拦截器链的代码。

到目前为止,我们知道,这个AspectJAfterThrowingAdvice拦截器,会通过递归调用,来执行拦截器链中的下一个拦截器。

而由于这里有try catch的处理,所以当执行拦截器链报错时,并且抛出的异常是指定抛出类型的子类型时,那么就会通过反射的方式,来执行切面中定义的AfterThrowing增强方法了。

所以这就从源码的角度,解释了AfterThrowing增强方法只有在有异常时才会执行的原因。

好了,那我们接着往下分析,此时就会继续递归调用,其实也就意味着,会接着往下执行拦截器链中的拦截器。

那么在递归调用时,接下来又会执行拦截器链中的哪一个拦截器呢?

image.png

此时拦截器链下标currentInterceptorIndex再次通过++操作后,会由1变为2,而拦截器链中下标为2的拦截器就是AfterReturningAdviceInterceptor了,也就是说下一个要执行的拦截器就是AfterReturningAdviceInterceptor了。

image.png

通过上图,可以看到,首先调用ExposeInvocationInterceptor拦截器将拦截器链暴露到ThreadLocal中后,接着通过递归调用了AspectJAfterThrowingAdvice拦截器。

而在AspectJAfterThrowingAdvice拦截器中,直接进行递归操作,而这次递归操作呢,调用的其实就是AfterReturningAdviceInterceptor拦截器了。

所以现在看来,拦截器中最核心的操作,其实就是这个递归调用,通过这个递归调用,可以将这些拦截器串成一根链条。

拦截器ExposeInvocationInterceptor和AspectJAfterThrowingAdvice的核心逻辑,现在大家知道,其实拦截器的核心逻辑,就是不断的递归调用ReflectiveMethodInvocation,而通过每个拦截器中的递归调用,就可以将这些拦截器串成一根链条。

同时每个拦截器中还会实现自己的一些增强逻辑,比如ExposeInvocationInterceptor拦截器实现了同线程共用拦截器链的功能,而AspectJAfterThrowingAdvice拦截器在有异常的时候,会来调用执行AfterThrowing增强方法。

那我们也知道,aspectJ一共有5种增强,那其他的增强,是不是也会不断的递归调用ReflectiveMethodInvocation呢?其他的增强又是怎么实现它自己的增强逻辑的?

AfterReturning增强:未发生异常才会执行

java @Override public Object invoke(MethodInvocation mi) throws Throwable { Object retVal = mi.proceed(); this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis()); return retVal; }

通过上边的代码,我们可以看到,其实这里还是通过mi.proceed()这行代码递归调用了ReflectiveMethodInvocation。

并且我们还可以看到,这里是没有try catch处理的,而是在方法mi.proceed()正常返回之后,会执行this.advice.afterReturning()方法。

那么如果执行mi.proceed()方法发生了异常,此时就不会执行afterReturning()方法了,而只有正常执行结束时,才会来执行AfterReturning增强逻辑。

所以现在我们从源码的角度,解释了AfterReturning增强只有在未发生异常时,才会执行的原因!

那AfterReturning增强具体是怎么执行的呢?

java @Override public Object invoke(MethodInvocation mi) throws Throwable { //返回值 Object retVal = mi.proceed(); //afterReturn方法 this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis()); return retVal; }

大家可以看到,执行AfterReturning增强其实是通过invokeAdviceMethod()方法完成的。

而invokeAdviceMethod()方法的代码,之前我们已经分析过了,具体的代码如下:

java protected Object invokeAdviceMethod(@Nullable JoinPointMatch jpMatch, @Nullable Object returnValue, @Nullable Throwable ex)throws Throwable { return invokeAdviceMethodWithGivenArgs(argBinding(getJoinPoint(), jpMatch, returnValue, ex)); }

java protected Object invokeAdviceMethodWithGivenArgs(Object[] args) throws Throwable { Object[] actualArgs = args; if (this.aspectJAdviceMethod.getParameterCount() == 0) { actualArgs = null; } try { ReflectionUtils.makeAccessible(this.aspectJAdviceMethod); // 牛逼呀 获取Aspect类的实例 然后调用方法 return this.aspectJAdviceMethod.invoke (this.aspectInstanceFactory.getAspectInstance(), actualArgs); } catch (IllegalArgumentException ex) { throw new AopInvocationException("Mismatch on arguments to advice method [" + this.aspectJAdviceMethod + "]; pointcut expression [" + this.pointcut.getPointcutExpression() + "]", ex); } catch (InvocationTargetException ex) { throw ex.getTargetException(); } }

其实invokeAdviceMethod()方法主要是通过调用invokeAdviceMethodWithGivenArgs()方法完成功能的,而invokeAdviceMethodWithGivenArgs()方法中关键的其实就一行代码,那就是this.aspectJAdviceMethod.invoke()这行代码

说白了就是通过反射调用了增强方法,而这个aspectJAdviceMethod我们上节讲过了,aspectJAdviceMethod其实就是切面中定义的增强方法,在这里其实就是AfterReturning增强方法。

此时拦截器链下标currentInterceptorIndex经过++操作后已经变为3了,所以下边会来获取并执行下标为3的拦截器,也就是AspectJAfterAdvice拦截器。

和之前的套路一样,都是先递归调用ReflectiveMethodInvocation,等递归调用完成后再执行AfterReturning增强,而这次递归调用的拦截器,其实就是AspectJAfterAdvice拦截器了。

After增强:无论是否有异常都会执行

接下来就轮到执行AspectJAfterAdvice拦截器了,AspectJAfterAdvice代码

java @Override public Object invoke(MethodInvocation mi) throws Throwable { try { return mi.proceed(); } finally { invokeAdviceMethod(getJoinPointMatch(), null, null); } }

上边的这块代码非常非常简单,还是递归调用ReflectiveMethodInvocation,大家看到了吧,还是原来的配方,还是熟悉的味道。

需要注意的是,这里是一个try finally语句,而在finally语句块中,调用了invokeAdviceMethod()方法,而这个方法的代码,我们已经讲过很多遍了,说白了就是通过反射来调用对应的增强方法,在这里,其实就是调用在切面中定义的After增强方法。

我们最后再来看一次invokeAdviceMethod()方法的代码,其实就是直接通过反射来执行了增强方法,非常简单。

其实最重要的还是要将整个AOP链路串起来,结合上下文来理解,这个增强方法aspectJAdviceMethod就是之前获取拦截器时,在创建Advice的时候进行赋值的,就是切面中定义的增强方法,大家忘记的话,可以回头看下获取拦截器的流程。

我们可以看到,增强方法的执行逻辑是放在finally语句块中的

所以这就从源码的角度,解释了无论是否有异常,After增强都会执行的原因,因为After增强的本质就是一个finally语句块!

此时拦截器链下标currentInterceptorIndex通过++操作后值变为4,因此接下来就会来获取并执行下标为4的拦截器,也就是AspectJAroundAdvice拦截器了,也就是说,下一个要执行的拦截器是AspectJAroundAdvice拦截器了。

Around增强:目标方法前后均可添加逻辑

已经没有递归调用ReflectiveMethodInvocation了,而是直接通过invokeAdviceMethod()方法调用了Around增强方法。

而这个invokeAdviceMethod()方法我们上边也分析很多遍了,其实就是通过反射的方式,调用了切面中定义的增强方法,而这里调用的就是切面中定义的Around增强方法。

java @Override public Object invoke(MethodInvocation mi) throws Throwable { if (!(mi instanceof ProxyMethodInvocation)) { throw new IllegalStateException ("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi); } ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi; ProceedingJoinPoint pjp = lazyGetProceedingJoinPoint(pmi); //注意这个pjp是对ReflectiveMethodInvocation的包装 JoinPointMatch jpm = getJoinPointMatch(pmi); return invokeAdviceMethod(pjp, jpm, null, null); }

而这个invokeAdviceMethod()方法我们上边也分析很多遍了,其实就是通过反射的方式,调用了切面中定义的增强方法,而这里调用的就是切面中定义的Around增强方法,其实就是下边这个方法,如下图:

java @Around("pointCut()") public void Around(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("Around Before1"); joinPoint.proceed(); System.out.println("Around After"); }

此时就会来执行我们日志切面中定义的Around增强方法了,首先就是执行Around前置增强逻辑,说白了就是打印了一行日志。

接着就会执行Object proceed = point.proceed()这行代码,那这个 point.proceed()是干嘛的呢?

java @Override public Object proceed() throws Throwable { return this.methodInvocation.invocableClone().proceed(); }

那就是this.methodInvocation.invocableClone().proceed(),通过这行代码,我们知道,其实最终就是调用了一个proceed()方法罢了,那么关键就是this.methodInvocation.invocableClone()的执行结果到底是那个对象!

其实这个简单,我们来看下这个this.methodInvocation.invocableClone()的运行结果就可以了,如下图:

image.png

其实this.methodInvocation.invocableClone()这行代码的运行结果,就是ReflectiveMethodInvocation类的一个实例,那也就是说this.methodInvocation.invocableClone().proceed()这行代码本质,还是递归调用了ReflectiveMethodInvocation类的proceed()方法。

也就是说,Around增强方法在执行时,会首先执行point.proceed()完前边的代码,也就是Around前置增强,接着就会使用point.proceed()递归调用ReflectiveMethodInvocation类的proceed(),等递归返回执行结果后,才会执行Around后置增强。

image.png

我们可以看到,拦截器链下标currentInterceptorIndex进行++操作后值为5,因此接下来会获取并执行下标为5的拦截器,也就是MethodBeforeAdviceInterceptor拦截器了。

通过上图,大家可以看到,AspectJAroundAdvice拦截器先执行了Around前置增强,接着递归调用了ReflectiveMethodInvocation,从而会来执行拦截器MethodBeforeAdviceInterceptor。

Before增强:目标方法前执行

java @Override public Object invoke(MethodInvocation mi) throws Throwable { this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis()); return mi.proceed(); }

这里首先会执行Before增强方法,然后接着会通过mi.proceed()递归调用ReflectiveMethodInvocation,代码其实是非常清晰的。那Before增强方法是怎么执行的呢?

其实上边这个before()方法,也是通过调用invokeAdviceMethod()方法完成的,而这个invokeAdviceMethod()方法我们知道,它就是通过反射,直接调用了切面中定义的增强方法,这里就不再赘述了。

before()方法执行完毕后,接着就会递归调用ReflectiveMethodInvocation了,此时就又回到这个proceed()方法了

不知道大家有没有想过一个问题,那就是既然是递归调用,那总不能一直递归下去吧?总要有一个递归结束的条件吧?

其实是这样的,上图红框中的代码就是递归的结束条件!大家还记得这个currentInterceptorIndex下标现在已经变为多少了吗?

其实此时这个currentInterceptorIndex变量经过一次又一次的++操作后,现在已经变为5了,我们看下边这张图:

image.png

此时currentInterceptorIndex变量已经累加到5了,而拦截器链中一共有6个拦截器,那么拦截器的size-1的结果就为5,那此时上图中的if条件就会成立!

说白了就是this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1这行代码会返回true,所以本次调用proceed()方法,就会执行return invokeJoinpoint()这行代码。而invokeJoinpoint()这个方法,我们在之前分析过,它其实就是用于调用目标方法的。

到目前为止,拦截器链就全部执行一遍了。我们来简单总结一下,到这里为止都执行了哪些增强。

首先是在AspectJAroundAdvice拦截器中执行了Around前置增强,然后接着在MethodBeforeAdviceInterceptor拦截器中执行了Before增强。

非常关键的一点是,在MethodBeforeAdviceInterceptor拦截器递归调用ReflectiveMethodInvocation的proceed()方法时,发现这个时候,递归结束条件成立了,此时就会执行目标方法!

所以,目前为止的执行流程是这样的:Around前置增强 -> Before增强 -> 目标方法

但现在有个问题就是,除了Around前置增强和Before增强外,其余的增强还都是没有执行的状态!

那么什么时候会执行其他增强方法呢?

其实这个非常简单,因为之前是不断的递归调用ReflectiveMethodInvocation的proceed()方法,而此时满足了递归结束的条件,那么此时在递归的过程中,调用的方法就会层层返回,这样其他的增强就会得到执行了。

我们可以总结出aspectJ五种增强的执行顺序,如下:

md 1. Around前置增强(AspectJAroundAdvice负责处理) 2. Before增强(MethodBeforeAdviceInterceptor负责处理) 3. 目标方法 4. Around后置增强(AspectJAroundAdvice负责处理) 5. After增强(AspectJAfterAdvice负责处理,无论是否有异常,都会执行) 6. AfterReturning增强(AfterReturningAdviceInterceptor负责处理,没有异常时,才会执行) 7. AfterThrowing增强(AspectJAfterThrowingAdvice负责处理,有异常时,才会执行)

其中需要注意的是,AfterReturning增强和AfterThrowing增强不会同时执行,而是只会执行其中一个

可以看到,其实每一种拦截器都单独处理了一种增强,比如MethodBeforeAdviceInterceptor拦截器就是用来处理Before增强的,而AspectJAfterAdvice拦截器就是用来处理After增强的。

像这种每个组件都各自负责一部分功能,并且这些组件的调用关系组成了一根调用链条,大家有没有觉得这种玩儿法和一种设计模式非常相似?

没错,就是责任链模式,其实啊,AOP中拦截器链这一块的本质,就是使用了责任链模式,只不过这里是通过递归调用ReflectiveMethodInvocation的方式,将所有的拦截器组成了一根调用链条,但是本质它还是一个责任链模式的玩儿法。

AOP拦截器链流程图

image.png

答疑

proxiedInterfaces是目标类的所有需要被代理的接口,会对proxiedInterfaces中所有的接口代理吗?

是的,如果目标类实现了A B 2个接口 那么生成的代理类,可以用A或者B接收

```md @Component public class AopLog implements LogService,PrintService {

@Override
@Transactional("transactionManager")
public void log() {
        System.out.println("----log----");
}

@Override
@Transactional("transactionManager")
public void print() {
        System.out.println("----print----");
}

}

//如果使用的是JDK代理 即AopLog有接口 那么使用下面的 LogService aopLog = context.getBean("aopLog", LogService.class); aopLog.log(); PrintService printService = context.getBean("aopLog", PrintService.class); printService.print(); ```

最后贴一下代理类反编译以后的源码。

``` // // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // ​ package com.sun.proxy; ​ import aopAndTransaction.LogService; import aopAndTransaction.PrintService; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.lang.reflect.UndeclaredThrowableException; import org.aopalliance.aop.Advice; import org.springframework.aop.Advisor; import org.springframework.aop.SpringProxy; import org.springframework.aop.TargetSource; import org.springframework.aop.framework.Advised; import org.springframework.aop.framework.AopConfigException; import org.springframework.core.DecoratingProxy; ​ public final class $Proxy23 extends Proxy implements LogService, PrintService, SpringProxy, Advised, DecoratingProxy {    private static Method m1;    private static Method m13;    private static Method m22;    private static Method m23;    private static Method m19;    private static Method m24;    private static Method m5;    private static Method m11;    private static Method m15;    private static Method m14;    private static Method m0;    private static Method m25;    private static Method m17;    private static Method m4;    private static Method m12;    private static Method m8;    private static Method m3;    private static Method m2;    private static Method m27;    private static Method m21;    private static Method m28;    private static Method m20;    private static Method m6;    private static Method m7;    private static Method m16;    private static Method m10;    private static Method m26;    private static Method m9;    private static Method m18; ​    public $Proxy23(InvocationHandler var1) throws {        super(var1);   } ​    public final boolean equals(Object var1) throws {        try {            return (Boolean)super.h.invoke(this, m1, new Object[]{var1});       } catch (RuntimeException | Error var3) {            throw var3;       } catch (Throwable var4) {            throw new UndeclaredThrowableException(var4);       }   } ​    public final boolean isExposeProxy() throws {        try {            return (Boolean)super.h.invoke(this, m13, (Object[])null);       } catch (RuntimeException | Error var2) {            throw var2;       } catch (Throwable var3) {            throw new UndeclaredThrowableException(var3);       }   } ​    public final void addAdvisor(Advisor var1) throws AopConfigException {        try {            super.h.invoke(this, m22, new Object[]{var1});       } catch (RuntimeException | Error var3) {            throw var3;       } catch (Throwable var4) {            throw new UndeclaredThrowableException(var4);       }   } ​    public final boolean isProxyTargetClass() throws {        try {            return (Boolean)super.h.invoke(this, m23, (Object[])null);       } catch (RuntimeException | Error var2) {            throw var2;       } catch (Throwable var3) {            throw new UndeclaredThrowableException(var3);       }   } ​    public final void removeAdvisor(int var1) throws AopConfigException {        try {            super.h.invoke(this, m19, new Object[]{var1});       } catch (RuntimeException | Error var3) {            throw var3;       } catch (Throwable var4) {            throw new UndeclaredThrowableException(var4);       }   } ​    public final Class[] getProxiedInterfaces() throws {        try {            return (Class[])super.h.invoke(this, m24, (Object[])null);       } catch (RuntimeException | Error var2) {            throw var2;       } catch (Throwable var3) {            throw new UndeclaredThrowableException(var3);       }   } ​    public final int indexOf(Advisor var1) throws {        try {            return (Integer)super.h.invoke(this, m5, new Object[]{var1});       } catch (RuntimeException | Error var3) {            throw var3;       } catch (Throwable var4) {            throw new UndeclaredThrowableException(var4);       }   } ​    public final TargetSource getTargetSource() throws {        try {            return (TargetSource)super.h.invoke(this, m11, (Object[])null);       } catch (RuntimeException | Error var2) {            throw var2;       } catch (Throwable var3) {            throw new UndeclaredThrowableException(var3);       }   } ​    public final void addAdvice(int var1, Advice var2) throws AopConfigException {        try {            super.h.invoke(this, m15, new Object[]{var1, var2});       } catch (RuntimeException | Error var4) {            throw var4;       } catch (Throwable var5) {            throw new UndeclaredThrowableException(var5);       }   } ​    public final void addAdvice(Advice var1) throws AopConfigException {        try {            super.h.invoke(this, m14, new Object[]{var1});       } catch (RuntimeException | Error var3) {            throw var3;       } catch (Throwable var4) {            throw new UndeclaredThrowableException(var4);       }   } ​    public final int hashCode() throws {        try {            return (Integer)super.h.invoke(this, m0, (Object[])null);       } catch (RuntimeException | Error var2) {            throw var2;       } catch (Throwable var3) {            throw new UndeclaredThrowableException(var3);       }   } ​    public final boolean isInterfaceProxied(Class var1) throws {        try {            return (Boolean)super.h.invoke(this, m25, new Object[]{var1});       } catch (RuntimeException | Error var3) {            throw var3;       } catch (Throwable var4) {            throw new UndeclaredThrowableException(var4);       }   } ​    public final boolean removeAdvice(Advice var1) throws {        try {            return (Boolean)super.h.invoke(this, m17, new Object[]{var1});       } catch (RuntimeException | Error var3) {            throw var3;       } catch (Throwable var4) {            throw new UndeclaredThrowableException(var4);       }   } ​    public final void print() throws {        try {            super.h.invoke(this, m4, (Object[])null);       } catch (RuntimeException | Error var2) {            throw var2;       } catch (Throwable var3) {            throw new UndeclaredThrowableException(var3);       }   } ​    public final void setExposeProxy(boolean var1) throws {        try {            super.h.invoke(this, m12, new Object[]{var1});       } catch (RuntimeException | Error var3) {            throw var3;       } catch (Throwable var4) {            throw new UndeclaredThrowableException(var4);       }   } ​    public final void setTargetSource(TargetSource var1) throws {        try {            super.h.invoke(this, m8, new Object[]{var1});       } catch (RuntimeException | Error var3) {            throw var3;       } catch (Throwable var4) {            throw new UndeclaredThrowableException(var4);       }   } ​    public final Integer log() throws {        try {            return (Integer)super.h.invoke(this, m3, (Object[])null);       } catch (RuntimeException | Error var2) {            throw var2;       } catch (Throwable var3) {            throw new UndeclaredThrowableException(var3);       }   } ​    public final String toString() throws {        try {            return (String)super.h.invoke(this, m2, (Object[])null);       } catch (RuntimeException | Error var2) {            throw var2;       } catch (Throwable var3) {            throw new UndeclaredThrowableException(var3);       }   } ​    public final Class getTargetClass() throws {        try {            return (Class)super.h.invoke(this, m27, (Object[])null);       } catch (RuntimeException | Error var2) {            throw var2;       } catch (Throwable var3) {            throw new UndeclaredThrowableException(var3);       }   } ​    public final void addAdvisor(int var1, Advisor var2) throws AopConfigException {        try {            super.h.invoke(this, m21, new Object[]{var1, var2});       } catch (RuntimeException | Error var4) {            throw var4;       } catch (Throwable var5) {            throw new UndeclaredThrowableException(var5);       }   } ​    public final Class getDecoratedClass() throws {        try {            return (Class)super.h.invoke(this, m28, (Object[])null);       } catch (RuntimeException | Error var2) {            throw var2;       } catch (Throwable var3) {            throw new UndeclaredThrowableException(var3);       }   } ​    public final boolean removeAdvisor(Advisor var1) throws {        try {            return (Boolean)super.h.invoke(this, m20, new Object[]{var1});       } catch (RuntimeException | Error var3) {            throw var3;       } catch (Throwable var4) {            throw new UndeclaredThrowableException(var4);       }   } ​    public final int indexOf(Advice var1) throws {        try {            return (Integer)super.h.invoke(this, m6, new Object[]{var1});       } catch (RuntimeException | Error var3) {            throw var3;       } catch (Throwable var4) {            throw new UndeclaredThrowableException(var4);       }   } ​    public final boolean isFrozen() throws {        try {            return (Boolean)super.h.invoke(this, m7, (Object[])null);       } catch (RuntimeException | Error var2) {            throw var2;       } catch (Throwable var3) {            throw new UndeclaredThrowableException(var3);       }   } ​    public final boolean replaceAdvisor(Advisor var1, Advisor var2) throws AopConfigException {        try {            return (Boolean)super.h.invoke(this, m16, new Object[]{var1, var2});       } catch (RuntimeException | Error var4) {            throw var4;       } catch (Throwable var5) {            throw new UndeclaredThrowableException(var5);       }   } ​    public final void setPreFiltered(boolean var1) throws {        try {            super.h.invoke(this, m10, new Object[]{var1});       } catch (RuntimeException | Error var3) {            throw var3;       } catch (Throwable var4) {            throw new UndeclaredThrowableException(var4);       }   } ​    public final String toProxyConfigString() throws {        try {            return (String)super.h.invoke(this, m26, (Object[])null);       } catch (RuntimeException | Error var2) {            throw var2;       } catch (Throwable var3) {            throw new UndeclaredThrowableException(var3);       }   } ​    public final Advisor[] getAdvisors() throws {        try {            return (Advisor[])super.h.invoke(this, m9, (Object[])null);       } catch (RuntimeException | Error var2) {            throw var2;       } catch (Throwable var3) {            throw new UndeclaredThrowableException(var3);       }   } ​    public final boolean isPreFiltered() throws {        try {            return (Boolean)super.h.invoke(this, m18, (Object[])null);       } catch (RuntimeException | Error var2) {            throw var2;       } catch (Throwable var3) {            throw new UndeclaredThrowableException(var3);       }   } ​    static {        try {            m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));            m13 = Class.forName("org.springframework.aop.framework.Advised").getMethod("isExposeProxy");            m22 = Class.forName("org.springframework.aop.framework.Advised").getMethod("addAdvisor", Class.forName("org.springframework.aop.Advisor"));            m23 = Class.forName("org.springframework.aop.framework.Advised").getMethod("isProxyTargetClass");            m19 = Class.forName("org.springframework.aop.framework.Advised").getMethod("removeAdvisor", Integer.TYPE);            m24 = Class.forName("org.springframework.aop.framework.Advised").getMethod("getProxiedInterfaces");            m5 = Class.forName("org.springframework.aop.framework.Advised").getMethod("indexOf", Class.forName("org.springframework.aop.Advisor"));            m11 = Class.forName("org.springframework.aop.framework.Advised").getMethod("getTargetSource");            m15 = Class.forName("org.springframework.aop.framework.Advised").getMethod("addAdvice", Integer.TYPE, Class.forName("org.aopalliance.aop.Advice"));            m14 = Class.forName("org.springframework.aop.framework.Advised").getMethod("addAdvice", Class.forName("org.aopalliance.aop.Advice"));            m0 = Class.forName("java.lang.Object").getMethod("hashCode");            m25 = Class.forName("org.springframework.aop.framework.Advised").getMethod("isInterfaceProxied", Class.forName("java.lang.Class"));            m17 = Class.forName("org.springframework.aop.framework.Advised").getMethod("removeAdvice", Class.forName("org.aopalliance.aop.Advice"));            m4 = Class.forName("aopAndTransaction.PrintService").getMethod("print");            m12 = Class.forName("org.springframework.aop.framework.Advised").getMethod("setExposeProxy", Boolean.TYPE);            m8 = Class.forName("org.springframework.aop.framework.Advised").getMethod("setTargetSource", Class.forName("org.springframework.aop.TargetSource"));            m3 = Class.forName("aopAndTransaction.LogService").getMethod("log");            m2 = Class.forName("java.lang.Object").getMethod("toString");            m27 = Class.forName("org.springframework.aop.framework.Advised").getMethod("getTargetClass");            m21 = Class.forName("org.springframework.aop.framework.Advised").getMethod("addAdvisor", Integer.TYPE, Class.forName("org.springframework.aop.Advisor"));            m28 = Class.forName("org.springframework.core.DecoratingProxy").getMethod("getDecoratedClass");            m20 = Class.forName("org.springframework.aop.framework.Advised").getMethod("removeAdvisor", Class.forName("org.springframework.aop.Advisor"));            m6 = Class.forName("org.springframework.aop.framework.Advised").getMethod("indexOf", Class.forName("org.aopalliance.aop.Advice"));            m7 = Class.forName("org.springframework.aop.framework.Advised").getMethod("isFrozen");            m16 = Class.forName("org.springframework.aop.framework.Advised").getMethod("replaceAdvisor", Class.forName("org.springframework.aop.Advisor"), Class.forName("org.springframework.aop.Advisor"));            m10 = Class.forName("org.springframework.aop.framework.Advised").getMethod("setPreFiltered", Boolean.TYPE);            m26 = Class.forName("org.springframework.aop.framework.Advised").getMethod("toProxyConfigString");            m9 = Class.forName("org.springframework.aop.framework.Advised").getMethod("getAdvisors");            m18 = Class.forName("org.springframework.aop.framework.Advised").getMethod("isPreFiltered");       } catch (NoSuchMethodException var2) {            throw new NoSuchMethodError(var2.getMessage());       } catch (ClassNotFoundException var3) {            throw new NoClassDefFoundError(var3.getMessage());       }   } }

```

参考: Spring AOP MethodInvocation拦截器调用原理

参考:https://blog.csdn.net/chaitoudaren/article/details/105278762

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值