spring AOP源码解析

1、AOP简介

AOP:【动态代理】

  •  指在程序运行期间动态的将某段代码切入到指定方法指定位置进行运行的编程方式;常用于日志处理,事物处理等统一性操作
    
2、使用说明
  • 1、导入aop模块;Spring AOP:(spring-aspects)
  • 2、定义一个业务逻辑类;在业务逻辑运行的时候将日志进行打印(方法之前、方法运行结束、方法出现异常,xxx)
  • 3、定义一个日志切面类:切面类里面的方法需要动态感知业务类方法运行到哪里然后执行;
  • 前置通知(@Before):logStart:在目标方法运行之前运行
  • 后置通知(@After):logEnd:在目标方法运行结束之后运行(无论方法正常结束还是异常结束)
  • 返回通知(@AfterReturning):logReturn:在目标方法正常返回之后运行
  • 异常通知(@AfterThrowing):logException:在目标方法出现异常以后运行
  • 环绕通知(@Around):动态代理,手动推进目标方法运行(joinPoint.procced())
  • 4、给切面类的目标方法标注何时何地运行(通知注解);
  • 5、将切面类和业务逻辑类(目标方法所在类)都加入到容器中;
  • 6、必须告诉Spring哪个类是切面类(给切面类上加一个注解:@Aspect)
  • 7、给配置类中加 @EnableAspectJAutoProxy 【开启基于注解的aop模式】
  •  在Spring中很多的 @EnableXXX;
    
总结:

1)将业务逻辑组件和切面类都加入到容器中;告诉Spring哪个是切面类(@Aspect)
2)在切面类上的每一个通知方法上标注通知注解,告诉Spring何时何地运行(切入点表达式)
3)开启基于注解的aop模式;@EnableAspectJAutoProxy

3、AOP代理对象生成源码分析
(1)@EnableAspectJAutoProxy注解

Spring中很多的 @EnableXXX类似注解,用于自动开启配置某些功能。分析源码时我们可以从这些注解入手
注意代码中的AspectJAutoProxyRegistrarspring通常通过impot注册相关组件完成功能开启

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
# 此处的import为重点导入AspectJAutoProxyRegistrar组件
@Import({AspectJAutoProxyRegistrar.class})
public @interface EnableAspectJAutoProxy {
    boolean proxyTargetClass() default false;

    boolean exposeProxy() default false;
}

AspectJAutoProxyRegistrar内主要导入了AnnotationAwareAspectJAutoProxyCreator组件,下面主要分析AnnotationAwareAspectJAutoProxyCreator具体操作及功能

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
    AspectJAutoProxyRegistrar() {
    }

    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
# 导入了`AnnotationAwareAspectJAutoProxyCreator`组件
        AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
        AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
        if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
            AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
        }

        if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
            AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
        }

    }
}

AnnotationAwareAspectJAutoProxyCreator主要继承接口关系,从继承关系可以看到此组件最终实现了awareBeanPostProcessor相关接口

AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator
extends AspectJAwareAdvisorAutoProxyCreator
extends AbstractAdvisorAutoProxyCreator
extends AbstractAutoProxyCreator implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware
关注后置处理器(在bean初始化完成前后做事情)、自动装配BeanFactory

BeanFactoryAwaresetBeanFactory内完成代理构造器的初始化,在SmartInstantiationAwareBeanPostProcessorpostProcessBeforeInstantiationpostProcessAfterInitialization内完成代理对象的包装,简单的看下下面代码
AbstractAdvisorAutoProxyCreator内的setBeanFactory部分代码

public void setBeanFactory(BeanFactory beanFactory) {
        super.setBeanFactory(beanFactory);
        if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
            throw new IllegalArgumentException("AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: " + beanFactory);
        } else {
            this.initBeanFactory((ConfigurableListableBeanFactory)beanFactory);
        }
    }

    protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        this.advisorRetrievalHelper = new AbstractAdvisorAutoProxyCreator.BeanFactoryAdvisorRetrievalHelperAdapter(beanFactory);
    }

AnnotationAwareAspectJAutoProxyCreator内的setBeanFactory部分代码

  protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
       super.initBeanFactory(beanFactory);
       if (this.aspectJAdvisorFactory == null) {
           this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
       }

       this.aspectJAdvisorsBuilder = new AnnotationAwareAspectJAutoProxyCreator.BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
   }

AbstractAdvisorAutoProxyCreatorAnnotationAwareAspectJAutoProxyCreator的两段代码中可以看出通过setBeanFactory完成代理构造器的初始化

再看下面关于SmartInstantiationAwareBeanPostProcessor接口实现的相关代码
AbstractAutoProxyCreator内下面postProcessBeforeInstantiation代码简单分析,

1、判断当前bean是否在advisedBeans中(保存了所有切面拦截bean
2、是否是切面通知相关的类AdvicePointcutAdvisorAopInfrastructureBean,如果是则直接加入需要加强集合advisedBeans中设置为false这部分bean不需要加强。
3、然后判断该类是否值自定义加强类型getCustomTargetSource若是则加强执行包装操作返回代理对象。

    public Object postProcessBeforeInstantiation(Class beanClass, String beanName) throws BeansException {
        Object cacheKey = this.getCacheKey(beanClass, beanName);
        if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {
            if (this.advisedBeans.containsKey(cacheKey)) {
                return null;
            }

            if (this.isInfrastructureClass(beanClass) || this.shouldSkip(beanClass, beanName)) {
                this.advisedBeans.put(cacheKey, Boolean.FALSE);
                return null;
            }
        }

        if (beanName != null) {
            TargetSource targetSource = this.getCustomTargetSource(beanClass, beanName);
            if (targetSource != null) {
                this.targetSourcedBeans.add(beanName);
                Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
                Object proxy = this.createProxy(beanClass, beanName, specificInterceptors, targetSource);
                this.proxyTypes.put(cacheKey, proxy.getClass());
                return proxy;
            }
        }

        return null;
    }

再看AbstractAutoProxyCreator内下面postProcessAfterInitialization代码简单分析
在bean实例化初始化完成之后,会在下面方法中判断是否需要包装加强对象代理

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean != null) {
            Object cacheKey = this.getCacheKey(bean.getClass(), beanName);
            if (!this.earlyProxyReferences.contains(cacheKey)) {
                return this.wrapIfNecessary(bean, beanName, cacheKey);
            }
        }

        return bean;
    }

wrapIfNecessary方法如下
加强判断步骤如下:

1、自定义加强bean和已经判断不需要加强的bean直接返回
2、判断属于advice等切面bean和需要跳过的bean直接返回bean,并且将bean加入不需要加强的bean集合中
3、除以上情况外,判断此bean有无能处理改类的advice拦截器,若有则将拦截器链排序生成代理对象返回
4、如果没有能处理的advice则将bean加入无需加强bean集合,直接返回改bean

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
            return bean;
        } else if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
            return bean;
        } else if (!this.isInfrastructureClass(bean.getClass()) && !this.shouldSkip(bean.getClass(), beanName)) {
            Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);
            if (specificInterceptors != DO_NOT_PROXY) {
                this.advisedBeans.put(cacheKey, Boolean.TRUE);
                Object proxy = this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
                this.proxyTypes.put(cacheKey, proxy.getClass());
                return proxy;
            } else {
                this.advisedBeans.put(cacheKey, Boolean.FALSE);
                return bean;
            }
        } else {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return bean;
        }
    }

适用的拦截器链条查找分析AbstractAdvisorAutoProxyCreator中的findEligibleAdvisorsAopUtils.findAdvisorsThatCanApply方法。
主要逻辑为:遍历判断所有的加强器,是否适用于该bean,通过canApply方法中的ClassFilter接口的matches方法判断,此处的ClassFilter实现类为AspectJExpressionPointcut通过此类的matches匹配切入点是否适用该bean

AbstractAdvisorAutoProxyCreator中的findEligibleAdvisors

protected List findEligibleAdvisors(Class beanClass, String beanName) {
        List candidateAdvisors = this.findCandidateAdvisors();
        List eligibleAdvisors = this.findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
        this.extendAdvisors(eligibleAdvisors);
        if (!eligibleAdvisors.isEmpty()) {
            eligibleAdvisors = this.sortAdvisors(eligibleAdvisors);
        }

        return eligibleAdvisors;
    }

AopUtils.findAdvisorsThatCanApply方法

public static List findAdvisorsThatCanApply(List candidateAdvisors, Class clazz) {
        if (candidateAdvisors.isEmpty()) {
            return candidateAdvisors;
        } else {
            List eligibleAdvisors = new LinkedList();
            Iterator var3 = candidateAdvisors.iterator();

            while(var3.hasNext()) {
                Advisor candidate = (Advisor)var3.next();
                if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
                    eligibleAdvisors.add(candidate);
                }
            }

            boolean hasIntroductions = !eligibleAdvisors.isEmpty();
            Iterator var7 = candidateAdvisors.iterator();

            while(var7.hasNext()) {
                Advisor candidate = (Advisor)var7.next();
                if (!(candidate instanceof IntroductionAdvisor) && canApply(candidate, clazz, hasIntroductions)) {
                    eligibleAdvisors.add(candidate);
                }
            }

            return eligibleAdvisors;
        }
    }
    public static boolean canApply(Pointcut pc, Class targetClass, boolean hasIntroductions) {
        Assert.notNull(pc, "Pointcut must not be null");
        if (!pc.getClassFilter().matches(targetClass)) {
            return false;
        } else {
            MethodMatcher methodMatcher = pc.getMethodMatcher();
            if (methodMatcher == MethodMatcher.TRUE) {
                return true;
            } else {
                IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
                if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
                    introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher)methodMatcher;
                }

                Set> classes = new LinkedHashSet(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
                classes.add(targetClass);
                Iterator var6 = classes.iterator();

                while(var6.hasNext()) {
                    Class clazz = (Class)var6.next();
                    Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
                    Method[] var9 = methods;
                    int var10 = methods.length;

                    for(int var11 = 0; var11 < var10; ++var11) {
                        Method method = var9[var11];
                        if (introductionAwareMethodMatcher != null && introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) || methodMatcher.matches(method, targetClass)) {
                            return true;
                        }
                    }
                }

                return false;
            }
        }
    }

AspectJExpressionPointcutmatches方法

public boolean matches(Class targetClass) {
        this.checkReadyToMatch();

        try {
            try {
                return this.pointcutExpression.couldMatchJoinPointsInType(targetClass);
            } catch (ReflectionWorldException var4) {
                logger.debug("PointcutExpression matching rejected target class - trying fallback expression", var4);
                PointcutExpression fallbackExpression = this.getFallbackPointcutExpression(targetClass);
                if (fallbackExpression != null) {
                    return fallbackExpression.couldMatchJoinPointsInType(targetClass);
                }
            }
        } catch (Throwable var5) {
            logger.debug("PointcutExpression matching rejected target class", var5);
        }

        return false;
    }

PointcutExpression实现方法

    public boolean couldMatchJoinPointsInType(Class aClass) {
        ResolvedType matchType = this.world.resolve(aClass.getName());
        if (matchType.isMissing() && this.world instanceof ReflectionWorld) {
            matchType = ((ReflectionWorld)this.world).resolveUsingClass(aClass);
        }

        ReflectionFastMatchInfo info = new ReflectionFastMatchInfo(matchType, (Kind)null, this.matchContext, this.world);
        boolean couldMatch = this.pointcut.fastMatch(info).maybeTrue();
        return couldMatch;
    }

代理对象生成分析:
通过ProxyFactory根据相应属性创建代理对象,首先创建AopProxy
根据bean是否继承接口,生成ObjenesisCglibAopProxy或者JdkDynamicAopProxy
然后getProxy获取代理对象

protected Object createProxy(Class beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
        if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
            AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory)this.beanFactory, beanName, beanClass);
        }

        ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.copyFrom(this);
        if (!proxyFactory.isProxyTargetClass()) {
            if (this.shouldProxyTargetClass(beanClass, beanName)) {
                proxyFactory.setProxyTargetClass(true);
            } else {
                this.evaluateProxyInterfaces(beanClass, proxyFactory);
            }
        }

        Advisor[] advisors = this.buildAdvisors(beanName, specificInterceptors);
        proxyFactory.addAdvisors(advisors);
        proxyFactory.setTargetSource(targetSource);
        this.customizeProxyFactory(proxyFactory);
        proxyFactory.setFrozen(this.freezeProxy);
        if (this.advisorsPreFiltered()) {
            proxyFactory.setPreFiltered(true);
        }

        return proxyFactory.getProxy(this.getProxyClassLoader());
    }

DefaultAopProxyFactory根据bean是否继承接口判断生成对象时,通过JDK动态代理还是Cglib生成代理对象。ObjenesisCglibAopProxy或者JdkDynamicAopProxy

  public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
      if (!config.isOptimize() && !config.isProxyTargetClass() && !this.hasNoUserSuppliedProxyInterfaces(config)) {
          return new JdkDynamicAopProxy(config);
      } else {
          Class targetClass = config.getTargetClass();
          if (targetClass == null) {
              throw new AopConfigException("TargetSource cannot determine target class: Either an interface or a target is required for proxy creation.");
          } else {
              return (AopProxy)(!targetClass.isInterface() && !Proxy.isProxyClass(targetClass) ? new ObjenesisCglibAopProxy(config) : new JdkDynamicAopProxy(config));
          }
      }
  }

我们看看ObjenesisCglibAopProxy生成代理过程

public Object getProxy(ClassLoader classLoader) {
        if (logger.isDebugEnabled()) {
            logger.debug("Creating CGLIB proxy: target source is " + this.advised.getTargetSource());
        }

        try {
            Class rootClass = this.advised.getTargetClass();
            Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
            Class proxySuperClass = rootClass;
            int x;
            if (ClassUtils.isCglibProxyClass(rootClass)) {
                proxySuperClass = rootClass.getSuperclass();
                Class[] additionalInterfaces = rootClass.getInterfaces();
                Class[] var5 = additionalInterfaces;
                int var6 = additionalInterfaces.length;

                for(x = 0; x < var6; ++x) {
                    Class additionalInterface = var5[x];
                    this.advised.addInterface(additionalInterface);
                }
            }

            this.validateClassIfNecessary(proxySuperClass, classLoader);
            Enhancer enhancer = this.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 CglibAopProxy.ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));
            Callback[] callbacks = this.getCallbacks(rootClass);
            Class[] types = new Class[callbacks.length];

            for(x = 0; x < types.length; ++x) {
                types[x] = callbacks[x].getClass();
            }

            enhancer.setCallbackFilter(new CglibAopProxy.ProxyCallbackFilter(this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
            enhancer.setCallbackTypes(types);
            return this.createProxyClassAndInstance(enhancer, callbacks);
        } catch (CodeGenerationException var9) {
            throw new AopConfigException("Could not generate CGLIB subclass of class [" + this.advised.getTargetClass() + "]: Common causes of this problem include using a final class or a non-visible class", var9);
        } catch (IllegalArgumentException var10) {
            throw new AopConfigException("Could not generate CGLIB subclass of class [" + this.advised.getTargetClass() + "]: Common causes of this problem include using a final class or a non-visible class", var10);
        } catch (Throwable var11) {
            throw new AopConfigException("Unexpected AOP exception", var11);
        }
    }

Callback[]获取设置,获取的时候会通过AdvisedSupportgetInterceptorsAndDynamicInterceptionAdvice方法匹配目标bean中每个方法的拦截链条Callback[]主要有FixedChainStaticTargetInterceptorDynamicAdvisedInterceptor,HashCodeInterceptor,HashCodeInterceptor包含AdvisedSupport(切面方法)并且实现MethodInterceptor接口,在调用代理对象方法时动态拦截执行intercept方法

private Callback[] getCallbacks(Class rootClass) throws Exception {
        boolean exposeProxy = this.advised.isExposeProxy();
        boolean isFrozen = this.advised.isFrozen();
        boolean isStatic = this.advised.getTargetSource().isStatic();
        Callback aopInterceptor = new CglibAopProxy.DynamicAdvisedInterceptor(this.advised);
        Object targetInterceptor;
        if (exposeProxy) {
            targetInterceptor = isStatic ? new CglibAopProxy.StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) : new CglibAopProxy.DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource());
        } else {
            targetInterceptor = isStatic ? new CglibAopProxy.StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) : new CglibAopProxy.DynamicUnadvisedInterceptor(this.advised.getTargetSource());
        }

        Callback targetDispatcher = (Callback)(isStatic ? new CglibAopProxy.StaticDispatcher(this.advised.getTargetSource().getTarget()) : new CglibAopProxy.SerializableNoOp());
        Callback[] mainCallbacks = new Callback[]{aopInterceptor, (Callback)targetInterceptor, new CglibAopProxy.SerializableNoOp(), targetDispatcher, this.advisedDispatcher, new CglibAopProxy.EqualsInterceptor(this.advised), new CglibAopProxy.HashCodeInterceptor(this.advised)};
        Callback[] callbacks;
        if (isStatic && isFrozen) {
            Method[] methods = rootClass.getMethods();
            Callback[] fixedCallbacks = new Callback[methods.length];
            this.fixedInterceptorMap = new HashMap(methods.length);

            for(int x = 0; x < methods.length; ++x) {
                List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(methods[x], rootClass);
                fixedCallbacks[x] = new CglibAopProxy.FixedChainStaticTargetInterceptor(chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
                this.fixedInterceptorMap.put(methods[x].toString(), x);
            }

            callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
            System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
            System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
            this.fixedInterceptorOffset = mainCallbacks.length;
        } else {
            callbacks = mainCallbacks;
        }

        return callbacks;
    }
 
 

总结:到此aop代理对象生成包装流程已经分析完成。主要由@EnableAspectJAutoProxy注解注入AnnotationAwareAspectJAutoProxyCreator组件。该组件实现BeanFactoryAwareSmartInstantiationAwareBeanPostProcessor接口。
BeanFactoryAwaresetBeanFactory 内完成代理构造器的初始化,在 SmartInstantiationAwareBeanPostProcessorpostProcessBeforeInstantiationpostProcessAfterInitialization内完成代理对象的包装。

4、AOP拦截执行时机分析

上面我们已经分析了动态代理对象,含有MethodInterceptor的拦截器集合,拦截器中又包含切面的方法。在执行intercept时,首先通过this.advised.getInterceptorsAndDynamicInterceptionAdvice获取拦截器(包装成实现org.aopalliance.intercept.MethodInterceptor的实现类)方法链。然后创建CglibMethodInvocation对象通过proceed依次执行拦截链方法。
DynamicAdvisedInterceptorintercept如下:
重点注意this.advised.getInterceptorsAndDynamicInterceptionAdvice方法根据方法和目标类获取拦截器链

public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
            Object oldProxy = null;
            boolean setProxyContext = false;
            Class targetClass = null;
            Object target = null;

            Object var15;
            try {
                if (this.advised.exposeProxy) {
                    oldProxy = AopContext.setCurrentProxy(proxy);
                    setProxyContext = true;
                }

                target = this.getTarget();
                if (target != null) {
                    targetClass = target.getClass();
                }

                List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
                Object retVal;
                if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
                    Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
                    retVal = methodProxy.invoke(target, argsToUse);
                } else {
                    retVal = (new CglibAopProxy.CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy)).proceed();
                }

                retVal = CglibAopProxy.processReturnType(proxy, target, method, retVal);
                var15 = retVal;
            } finally {
                if (target != null) {
                    this.releaseTarget(target);
                }

                if (setProxyContext) {
                    AopContext.setCurrentProxy(oldProxy);
                }

            }

            return var15;
        }
 
 

分析this.advised.getInterceptorsAndDynamicInterceptionAdvice方法,注意代码中AdvisorAdapterRegistry利用registry.getInterceptors(advisor);包装拦截器链

public List getInterceptorsAndDynamicInterceptionAdvice(Advised config, Method method, Class targetClass) {
        List interceptorList = new ArrayList(config.getAdvisors().length);
        Class actualClass = targetClass != null ? targetClass : method.getDeclaringClass();
        boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);
        AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
        Advisor[] var8 = config.getAdvisors();
        int var9 = var8.length;

        for(int var10 = 0; var10 < var9; ++var10) {
            Advisor advisor = var8[var10];
            MethodInterceptor[] interceptors;
            if (advisor instanceof PointcutAdvisor) {
                PointcutAdvisor pointcutAdvisor = (PointcutAdvisor)advisor;
                if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
                    interceptors = registry.getInterceptors(advisor);
                    MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
                    if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {
                        if (mm.isRuntime()) {
                            MethodInterceptor[] var15 = interceptors;
                            int var16 = interceptors.length;

                            for(int var17 = 0; var17 < var16; ++var17) {
                                MethodInterceptor interceptor = var15[var17];
                                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)) {
                    interceptors = registry.getInterceptors(advisor);
                    interceptorList.addAll(Arrays.asList(interceptors));
                }
            } else {
                Interceptor[] interceptors = registry.getInterceptors(advisor);
                interceptorList.addAll(Arrays.asList(interceptors));
            }
        }

        return interceptorList;
    }
 
 

DefaultAdvisorAdapterRegistrygetInterceptors方法通过AdvisorAdapter适配器包装拦截器。下面代码可以看到主要的AdvisorAdapterMethodBeforeAdviceAdapter,AfterReturningAdviceAdapter,ThrowsAdviceAdapter包装生成MethodBeforeAdviceInterceptor,AfterReturningAdviceInterceptor,ThrowsAdviceInterceptor对象

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

下面我们可以看到包装过程获取所有的适配器,判断如果支持该advice则适配生成拦截器对象然后加入拦截器链

public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
        List interceptors = new ArrayList(3);
        Advice advice = advisor.getAdvice();
        if (advice instanceof MethodInterceptor) {
            interceptors.add((MethodInterceptor)advice);
        }

        Iterator var4 = this.adapters.iterator();

        while(var4.hasNext()) {
            AdvisorAdapter adapter = (AdvisorAdapter)var4.next();
            if (adapter.supportsAdvice(advice)) {
                interceptors.add(adapter.getInterceptor(advisor));
            }
        }

        if (interceptors.isEmpty()) {
            throw new UnknownAdviceTypeException(advisor.getAdvice());
        } else {
            return (MethodInterceptor[])interceptors.toArray(new MethodInterceptor[interceptors.size()]);
        }
    }

在执行intercept时,会创建CglibMethodInvocation对象通过proceed执行拦截方法。

public Object proceed() throws Throwable {
        if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
            return this.invokeJoinpoint();
        } else {
            Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
            if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
                InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher)interceptorOrInterceptionAdvice;
                return dm.methodMatcher.matches(this.method, this.targetClass, this.arguments) ? dm.interceptor.invoke(this) : this.proceed();
            } else {
                return ((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this);
            }
        }
    }

我们看看MethodBeforeAdviceInterceptor,AfterReturningAdviceInterceptor,ThrowsAdviceInterceptor拦截器invoke的具体执行,下面三个方法都会执行mi.proceed();关于递归执行CglibMethodInvocationproceed方法知道执行索引等于链条的最后一个,MethodBeforeAdviceInterceptor会先执行前置处理方法
MethodBeforeAdviceInterceptor代码

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

MethodBeforeAdviceInterceptor代码

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

ThrowsAdviceInterceptor代码

public Object invoke(MethodInvocation mi) throws Throwable {
        try {
            return mi.proceed();
        } catch (Throwable var4) {
            Method handlerMethod = this.getExceptionHandler(var4);
            if (handlerMethod != null) {
                this.invokeHandlerMethod(mi, var4, handlerMethod);
            }

            throw var4;
        }
    }

我们看看拦截器链的顺序,会递归到链条的末端连接器然后依次执行连接器链方法


spring AOP源码解析_第1张图片

你可能感兴趣的:(spring AOP源码解析)