Spring源码(4):AOP实现

252 阅读10分钟

AOP中的一些概念

AOP代理实现

Spring基于注解实现AOP的类是AnnotationAwareAspectJAutoProxyCreator,该类的继承体系为 image.png

AnnotationAwareAspectJAutoProxyCreator的父类AbstractAutoProxyCreator实现了SmartInstantiationAwareBeanPostProcessor类,也就是上文所述的Bean创建的前后处理器。AbstractAutoProxyCreator中的postProcessBeforeInstantiation()postProcessAfterInitialization方法是实现AOP功能的关键方法。

postProcessBeforeInstantiation()在创建bean之前执行,获取全部的AOP代理类并解析缓存。postProcessAfterInitialization在bean初始化之后执行,实现类的代理。

代理前的准备

AbstractAutoProxyCreator的postProcessBeforeInstantiation()方法如下:

public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
   Object cacheKey = getCacheKey(beanClass, beanName);

   if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
      if (this.advisedBeans.containsKey(cacheKey)) {
         return null;
      }
      // shouldSkip()方法获取并解析已定义好的代理
      if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
         this.advisedBeans.put(cacheKey, Boolean.FALSE);
         return null;
      }
   }
}

shouldSkip()方法由子类AspectJAwareAdvisorAutoProxyCreator覆盖实现:

protected boolean shouldSkip(Class<?> beanClass, String beanName) {
   // 获取切面信息
   List<Advisor> candidateAdvisors = findCandidateAdvisors();
   for (Advisor advisor : candidateAdvisors) {
      if (advisor instanceof AspectJPointcutAdvisor &&
            ((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
         return true;
      }
   }
   return super.shouldSkip(beanClass, beanName);
}

findCandidateAdvisors()方法在AbstractAdvisorAutoProxyCreator中定义,该方法可以获取并解析非注解实现的AOP代理,而在AnnotationAwareAspectJAutoProxyCreator中覆盖实现的findCandidateAdvisors()方法,不仅可以获取并解析非注解实现的AOP代理,也可以获取并解析注解实现的AOP代理

protected List<Advisor> findCandidateAdvisors() {
   // 获取并解析非注解实现的AOP代理
   List<Advisor> advisors = super.findCandidateAdvisors();
       // 获取并解析注解实现的AOP代理
   if (this.aspectJAdvisorsBuilder != null) {
      advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
   }
   return advisors;
}

buildAspectJAdvisors()方法是可以获取并解析注解实现的AOP代理,并将解析好的结果放在缓存中,后续再获取列表时,可以直接从缓存中获取:

  1. 先遍历所有的类
  2. 判断该类是否是切面类
  3. 获取切面类Aspect的切面列表
  4. 保存切面类Aspect的切面列表到缓存advisorsCache中
public List<Advisor> buildAspectJAdvisors() {
   List<String> aspectNames = this.aspectBeanNames;

   if (aspectNames == null) {
      synchronized (this) {
         aspectNames = this.aspectBeanNames;
         if (aspectNames == null) {
            List<Advisor> advisors = new ArrayList<>();
            aspectNames = new ArrayList<>();
            String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                  this.beanFactory, Object.class, true, false);
            // 遍历所有的类
            for (String beanName : beanNames) {
               if (!isEligibleBean(beanName)) {
                  continue;
               }
               Class<?> beanType = this.beanFactory.getType(beanName, false);
               if (beanType == null) {
                  continue;
               }
               // 判断该类是否为切面类
               if (this.advisorFactory.isAspect(beanType)) {
                  aspectNames.add(beanName);
                  AspectMetadata amd = new AspectMetadata(beanType, beanName);
                  if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
                     MetadataAwareAspectInstanceFactory factory =
                           new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
                     // 获取并解析切面类,得到一个切面列表
                     List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
                     if (this.beanFactory.isSingleton(beanName)) {
                        // 缓存切面列表
                        this.advisorsCache.put(beanName, classAdvisors);
                     }
                     else {
                        this.aspectFactoryCache.put(beanName, factory);
                     }
                     advisors.addAll(classAdvisors);
                  }
                  else {
                     if (this.beanFactory.isSingleton(beanName)) {
                        throw new IllegalArgumentException("Bean with name '" + beanName +
                              "' is a singleton, but aspect instantiation model is not singleton");
                     }
                     MetadataAwareAspectInstanceFactory factory =
                           new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
                     this.aspectFactoryCache.put(beanName, factory);
                     advisors.addAll(this.advisorFactory.getAdvisors(factory));
                  }
               }
            }
            this.aspectBeanNames = aspectNames;
            return advisors;
         }
      }
   }

   if (aspectNames.isEmpty()) {
      return Collections.emptyList();
   }
   
   // 再次请求时,直接从切面列表中获取
   List<Advisor> advisors = new ArrayList<>();
   for (String aspectName : aspectNames) {
      List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
      if (cachedAdvisors != null) {
         advisors.addAll(cachedAdvisors);
      }
      else {
         MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
         advisors.addAll(this.advisorFactory.getAdvisors(factory));
      }
   }
   return advisors;
}

getAdvisors()方法在ReflectiveAspectJAdvisorFactory类中,该方法遍历切面类的所有切面方法,然后解析出切面,并添加到切面列表中

public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
   Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
   String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
   validate(aspectClass);

   MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
         new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);

   // 遍历该类的切面方法
   List<Advisor> advisors = new ArrayList<>();
   // getAdvisorMethods()获取该类的所有切面方法,并排序(按照切面优先级顺序排序)
   for (Method method : getAdvisorMethods(aspectClass)) {
      // 解析出切面
      Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, 0, aspectName);
      if (advisor != null) {
         advisors.add(advisor);
      }
   }

   if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
      Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
      advisors.add(0, instantiationAdvisor);
   }

   for (Field field : aspectClass.getDeclaredFields()) {
      Advisor advisor = getDeclareParentsAdvisor(field);
      if (advisor != null) {
         advisors.add(advisor);
      }
   }

   return advisors;
}

getAdvisor()方法则是创建一个InstantiationModelAwarePointcutAdvisorImpl对象并返回,其中解析切面方法是在该类的构造方法中完成

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;
   }

   return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
         this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}

InstantiationModelAwarePointcutAdvisorImpl在其构造方法中完成切面方法的解析

public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,
      Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,
      MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {

   // 参数赋值
   if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
      Pointcut preInstantiationPointcut = Pointcuts.union(
            aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);

      this.pointcut = new PerTargetInstantiationModelPointcut(
            this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory);
      this.lazy = true;
   }
   else {
      // A singleton aspect.
      this.pointcut = this.declaredPointcut;
      this.lazy = false;
      // 解析切面
      this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
   }
}

// 通过aspectJAdvisorFactory.getAdvice()获取一个Advice
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()方法是在ReflectiveAspectJAdvisorFactory类中,通过获取方法上的注解,并和AOP预先定义好的注解进行匹配,最后可以得到对应的增强类Advice

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

   Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
   validate(candidateAspectClass);
   
   // 解析方法上的注解
   AspectJAnnotation<?> aspectJAnnotation =
         AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
   if (aspectJAnnotation == null) {
      return null;
   }

   if (!isAspect(candidateAspectClass)) {
      throw new AopConfigException("Advice must be declared inside an aspect type: " +
            "Offending method '" + candidateAdviceMethod + "' in class [" +
            candidateAspectClass.getName() + "]");
   }

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

   AbstractAspectJAdvice springAdvice;

   // 注解和AOP预定义的注解进行匹配,然后返回对应的增强类Advice
   switch (aspectJAnnotation.getAnnotationType()) {
      case AtPointcut:
         if (logger.isDebugEnabled()) {
            logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
         }
         return null;
      case AtAround:
         springAdvice = new AspectJAroundAdvice(
               candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
         break;
      case AtBefore:
         springAdvice = new AspectJMethodBeforeAdvice(
               candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
         break;
      case AtAfter:
         springAdvice = new AspectJAfterAdvice(
               candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
         break;
      case AtAfterReturning:
         springAdvice = new AspectJAfterReturningAdvice(
               candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
         AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
         if (StringUtils.hasText(afterReturningAnnotation.returning())) {
            springAdvice.setReturningName(afterReturningAnnotation.returning());
         }
         break;
      case AtAfterThrowing:
         springAdvice = new AspectJAfterThrowingAdvice(
               candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
         AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
         if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
            springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
         }
         break;
      default:
         throw new UnsupportedOperationException(
               "Unsupported advice type on method: " + candidateAdviceMethod);
   }

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

   return springAdvice;
}

实现代理

AbstractAutoProxyCreator的postProcessAfterInitialization()方法如下:

public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
   if (bean != null) {
      Object cacheKey = getCacheKey(bean.getClass(), beanName);
      if (this.earlyProxyReferences.remove(cacheKey) != bean) {
         // 匹配切面列表,并生成代理
         return wrapIfNecessary(bean, beanName, cacheKey);
      }
   }
   return bean;
}

wrapIfNecessary()主要有两步,首先匹配所有的切面列表,然后再使用匹配到的切面列表创建代理

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
   if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
      return bean;
   }
   if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
      return bean;
   }
   if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
      this.advisedBeans.put(cacheKey, Boolean.FALSE);
      return bean;
   }

   // 匹配切面列表
   Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
   if (specificInterceptors != DO_NOT_PROXY) {
      this.advisedBeans.put(cacheKey, Boolean.TRUE);
      // 创建代理
      Object proxy = createProxy(
            bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
      this.proxyTypes.put(cacheKey, proxy.getClass());
      return proxy;
   }

   this.advisedBeans.put(cacheKey, Boolean.FALSE);
   return bean;
}

获取匹配的切面列表

getAdvicesAndAdvisorsForBean()由子类AbstractAdvisorAutoProxyCreator实现

protected Object[] getAdvicesAndAdvisorsForBean(
      Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
   
   // 匹配切面列表
   List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
   if (advisors.isEmpty()) {
      return DO_NOT_PROXY;
   }
   return advisors.toArray();
}

findEligibleAdvisors()首先查询出所有的切面列表,然后再遍历得出匹配当前类的切面列表。findCandidateAdvisors()方法由子类AnnotationAwareAspectJAutoProxyCreator实现,从上文创建切面列表中可以发现,本次调用findCandidateAdvisors()可以直接从缓存中获取全部的切面列表,而不需要再创建。

protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
   // 查询所有的切面列表
   List<Advisor> candidateAdvisors = findCandidateAdvisors();
   // 得到匹配当前bean的切面列表
   List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
   extendAdvisors(eligibleAdvisors);
   if (!eligibleAdvisors.isEmpty()) {
      eligibleAdvisors = sortAdvisors(eligibleAdvisors);
   }
   return eligibleAdvisors;
}

findAdvisorsThatCanApply()方法则是通过AopUtils工具类的findAdvisorsThatCanApply()方法获取匹配当前bean的切面列表

protected List<Advisor> findAdvisorsThatCanApply(
      List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {

   ProxyCreationContext.setCurrentProxiedBeanName(beanName);
   try {
      // 获取匹配当前bean的切面列表
      return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
   }
   finally {
      ProxyCreationContext.setCurrentProxiedBeanName(null);
   }
}

findAdvisorsThatCanApply()方法也并未实现真正的匹配逻辑,而是遍历了所有增强器,再调用canApply()方法获取匹配该bean的增强器,而canApply()方法则继续向下调用另外一个重载的canApply()方法

public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
   if (candidateAdvisors.isEmpty()) {
      return candidateAdvisors;
   }
   List<Advisor> eligibleAdvisors = new ArrayList<>();
   for (Advisor candidate : candidateAdvisors) {
      if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
         eligibleAdvisors.add(candidate);
      }
   }
   boolean hasIntroductions = !eligibleAdvisors.isEmpty();
   // 遍历所有增强器
   for (Advisor candidate : candidateAdvisors) {
      if (candidate instanceof IntroductionAdvisor) {
         // already processed
         continue;
      }
      // 将匹配当前bean的增强器加到结果列表中
      if (canApply(candidate, clazz, hasIntroductions)) {
         eligibleAdvisors.add(candidate);
      }
   }
   return eligibleAdvisors;
}

// 再继续向下调用另外一个重载的canApply方法
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
   if (advisor instanceof IntroductionAdvisor) {
      return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
   }
   else if (advisor instanceof PointcutAdvisor) {
      PointcutAdvisor pca = (PointcutAdvisor) advisor;
      return canApply(pca.getPointcut(), targetClass, hasIntroductions);
   }
   else {
      // It doesn't have a pointcut so we assume it applies.
      return true;
   }
}

canApply()遍历该bean的所有方法,然后一一和增强器匹配,匹配上则返回true

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;
   }

   MethodMatcher methodMatcher = pc.getMethodMatcher();
   if (methodMatcher == MethodMatcher.TRUE) {
      // No need to iterate the methods if we're matching any method anyway...
      return true;
   }

   IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
   if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
      introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
   }

   Set<Class<?>> classes = new LinkedHashSet<>();
   if (!Proxy.isProxyClass(targetClass)) {
      classes.add(ClassUtils.getUserClass(targetClass));
   }
   classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));

   for (Class<?> clazz : classes) {
      Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
      // 遍历该bean的所有方法
      for (Method method : methods) {
         // 增强器和方法匹配
         if (introductionAwareMethodMatcher != null ?
               introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
               methodMatcher.matches(method, targetClass)) {
            return true;
         }
      }
   }

   return false;
}

创建代理

得到匹配的切面列表后,再返回到wrapIfNecessary()方调用的createProxy()方法创建代理上

protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
      @Nullable 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 (Proxy.isProxyClass(beanClass)) {
         for (Class<?> ifc : beanClass.getInterfaces()) {
            proxyFactory.addInterface(ifc);
         }
      }
   }
   else {
      if (shouldProxyTargetClass(beanClass, beanName)) {
         proxyFactory.setProxyTargetClass(true);
      }
      else {
         evaluateProxyInterfaces(beanClass, proxyFactory);
      }
   }

   // 切面列表
   Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
   proxyFactory.addAdvisors(advisors);
   proxyFactory.setTargetSource(targetSource);
   customizeProxyFactory(proxyFactory);

   proxyFactory.setFrozen(this.freezeProxy);
   if (advisorsPreFiltered()) {
      proxyFactory.setPreFiltered(true);
   }

   // Use original ClassLoader if bean class not locally loaded in overriding class loader
   ClassLoader classLoader = getProxyClassLoader();
   if (classLoader instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) {
      classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader();
   }
   // 创建代理
   return proxyFactory.getProxy(classLoader);
}

// proxyFactory中的getProxy()方法
public Object getProxy(@Nullable ClassLoader classLoader) {
   return createAopProxy().getProxy(classLoader);
}

// ProxyFactory父类ProxyCreatorSupport中的createAopProxy()方法
protected final synchronized AopProxy createAopProxy() {
   if (!this.active) {
      activate();
   }
   return getAopProxyFactory().createAopProxy(this);
}

createAopProxy()是AopProxyFactory接口中定义的方法,具体实现在DefaultAopProxyFactory类中,createAopProxy()方法可以创建JDK代理和CGLB代理两种代理。

public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
   if (!NativeDetector.inNativeImage() &&
         (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))) {
      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.");
      }
      if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
         // 创建JDK代理
         return new JdkDynamicAopProxy(config);
      }
      // 创建CGLB代理
      return new ObjenesisCglibAopProxy(config);
   }
   else {
      // 创建JDK代理
      return new JdkDynamicAopProxy(config);
   }
}

创建好AopProxy代理对象后,再调用getProxy()方法获取代理,以JDK为例

// 构造方法,代理对象
public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
   Assert.notNull(config, "AdvisedSupport must not be null");
   if (config.getAdvisorCount() == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
      throw new AopConfigException("No advisors and no TargetSource specified");
   }
   this.advised = config;
   // 获取代理类应该实现的代理接口
   this.proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
   findDefinedEqualsAndHashCodeMethods(this.proxiedInterfaces);
}


// 获取代理
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
   if (logger.isTraceEnabled()) {
      logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
   }
   // 返回代理对象,代理类为JdkDynamicAopProxy
   return Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this);
}

因为JdkDynamicAopProxy类实现了InvocationHandler接口的invoke()方法,JdkDynamicAopProxy本身就是代理。

执行代理方法

当调用代理的方法时,实际上调用的是JdkDynamicAopProxy的invoke()方法

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 {
      // 不对equals和hashCode方法代理
      if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
         return equals(args[0]);
      }
      else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
         return hashCode();
      }
      // DecoratingProxy接口
      else if (method.getDeclaringClass() == DecoratingProxy.class) {
         return AopProxyUtils.ultimateTargetClass(this.advised);
      }
      // 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);

      // 切面列表的拦截器链
      List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

      if (chain.isEmpty()) {
         Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
         retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
      }
      else {
         // ReflectiveMethodInvocation控制拦截链chain一个一个执行
         MethodInvocation invocation =
               new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
         retVal = invocation.proceed();
      }

      Class<?> returnType = method.getReturnType();
      if (retVal != null && retVal == target &&
         retVal = proxy;
      }
      else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
         throw new AopInvocationException(
               "Null return value from advice does not match primitive return type for: " + method);
      }
      return retVal;
   }
   finally {
      if (target != null && !targetSource.isStatic()) {
         targetSource.releaseTarget(target);
      }
      if (setProxyContext) {
         AopContext.setCurrentProxy(oldProxy);
      }
   }
}

ReflectiveMethodInvocation拦截链的执行

1. Advisor和Advice的关系

一个Advisor(InstantiationModelAwarePointcutAdvisorImpl)是封装了一个Advice(五种通知),同时还封装了对应的Pointcut对象(AspectJExpressionPointcut)

2. Advice和MethodInterceptor的关系

image.png MethodInterceptor提供了一个接口功能叫intercept,使用此方法完成对执行方法的拦截,方便执行增强功能,Advice是MethodInterceptor的父接口。

Advice有五种通知@Around,@Before,@After,@Around,@AfterReturning,@AfterThrowing,其中

  • AspectJAfterAdvice(@After)
  • AspectJAroundAdvice(@Around)
  • AspectJAfterThrowingAdvice(@AfterThrowing)

实现了MethodInterceptor接口,而另外两种通知,没有直接实现MethodInterceptor接口,需要使用适配器

  • AfterReturningAdviceAdapter(@AfterReturning转为AfterReturningAdviceInterceptor)
  • MethodBeforeAdviceAdapter(@Before转为MethodBeforeAdviceInterceptor)

与MethodInterceptor接口建立联系。

// 支持的适配器
private final List<AdvisorAdapter> adapters = new ArrayList<>(3);

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

// 在invoke方法中获取拦截器链时会完成适配器的转换,整体的调用链为:
// 1.org.springframework.aop.framework.JdkDynamicAopProxy.invoke()
// 2.org.springframework.aop.framework.AdvisedSupport.getInterceptorsAndDynamicInterceptionAdvice()
// 3.org.springframework.aop.framework.DefaultAdvisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice()
// 4.org.springframework.aop.framework.adapter.DefaultAdvisorAdapterRegistry.getInterceptors()
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
   List<MethodInterceptor> interceptors = new ArrayList<>(3);
   Advice advice = advisor.getAdvice();
   // 直接实现了MethodInterceptor的Advice
   if (advice instanceof MethodInterceptor) {
      interceptors.add((MethodInterceptor) advice);
   }
   
   // 需要使用适配器的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]);
}
3. Advice的顺序

Advice的正常的执行顺序为@Around(before) –> @Before –> 逻辑 –> @AfterReturning -> @After -> @Around(after)

而Advice在列表中存放的顺序,则是在ReflectiveAspectJAdvisorFactory的getAdvisors()方法中遍历方法,通过getAdvisorMethods(aspectClass)获取待遍历的方法时排序

private List<Method> getAdvisorMethods(Class<?> aspectClass) {
   List<Method> methods = new ArrayList<>();
   ReflectionUtils.doWithMethods(aspectClass, methods::add, adviceMethodFilter);
   if (methods.size() > 1) {
      // 对方法进行排序,adviceMethodComparator为排序器
      methods.sort(adviceMethodComparator);
   }
   return methods;
}

// 排序器(ReflectiveAspectJAdvisorFactory类中)
private static final Comparator<Method> adviceMethodComparator;

static {
   // 该段注释解释@After在@AfterReturning和@AfterThrowing之后执行
   // Note: although @After is ordered before @AfterReturning and @AfterThrowing,
   // an @After advice method will actually be invoked after @AfterReturning and
   // @AfterThrowing methods due to the fact that AspectJAfterAdvice.invoke(MethodInvocation)
   // invokes proceed() in a `try` block and only invokes the @After advice method
   // in a corresponding `finally` block.
   
   Comparator<Method> adviceKindComparator = new ConvertingComparator<>(
         new InstanceComparator<>(
               Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class),
         (Converter<Method, Annotation>) method -> {
            AspectJAnnotation<?> ann = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(method);
            return (ann != null ? ann.getAnnotation() : null);
         });
   Comparator<Method> methodNameComparator = new ConvertingComparator<>(Method::getName);
   adviceMethodComparator = adviceKindComparator.thenComparing(methodNameComparator);
}
4. 执行拦截链

以@Around,@Before,@After三个注解,拦截器链执行逻辑为:

  • 首先在chain中的顺序为Around,Before,After
  • <获取拦截器,获取后currentInterceptorIndex=2> 获取第一个拦截器Around,执行invoke()方法
// 拦截器坐标,记录推进到了哪一个拦截器
private int currentInterceptorIndex = -1;

public Object proceed() throws Throwable {
   // 拦截器执行完,执行目标方法
   if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
      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 {
         return proceed();
      }
   }
   else {
      // 执行拦截器的invoke()方法
      return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
   }
}
  • <Around注解> AspectJAroundAdvice的invoke方法如下,传入的参数this被封装为ProceedingJoinPoint继续调用invokeAdviceMethod和invokeAdviceMethodWithGivenArgs方法
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);
   JoinPointMatch jpm = getJoinPointMatch(pmi);
   return invokeAdviceMethod(pjp, jpm, null, null);
}


protected Object invokeAdviceMethod(JoinPoint jp, @Nullable JoinPointMatch jpMatch,
      @Nullable Object returnValue, @Nullable Throwable t) throws Throwable {

   return invokeAdviceMethodWithGivenArgs(argBinding(jp, jpMatch, returnValue, t));
}
  • <Around注解> invokeAdviceMethodWithGivenArgs在调用aspectJAdviceMethod.invoke时,会进入到自定义的@Around切面中
protected Object invokeAdviceMethodWithGivenArgs(Object[] args) throws Throwable {
   Object[] actualArgs = args;
   if (this.aspectJAdviceMethod.getParameterCount() == 0) {
      actualArgs = null;
   }
   try {
      ReflectionUtils.makeAccessible(this.aspectJAdviceMethod);
      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();
   }
}
  • <Around注解> 进入到自定义的@Around切面逻辑并执行,调用proceedingJoinPoint.proceed()方法再获取下一个拦截器
@Around("myPointCut()")
public Object printAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
    System.out.println("around-before");
    // proceedingJoinPoint是上游传入的this
    Object result = proceedingJoinPoint.proceed();
    System.out.println("around-after");
    return result;
}
  • <获取拦截器 获取后currentInterceptorIndex=3> 再次进入ReflectiveMethodInvocation的proceed获取下一个拦截器@Before
  • <Before注解> MethodBeforeAdviceInterceptor的invoke方法如下,先执行自定义的@Before切面逻辑,然后再获取下一个拦截器
public Object invoke(MethodInvocation mi) throws Throwable {
    this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
    return mi.proceed();
}
  • <获取拦截器 获取后currentInterceptorIndex=4> 再次进入ReflectiveMethodInvocation的proceed获取下一个拦截器@After
  • <After注解> AspectJAfterAdvice的invoke方法如下,先执行proceed()方法继续获取下一个拦截器,再执行@After切面逻辑
public Object invoke(MethodInvocation mi) throws Throwable {
    try {
        return mi.proceed();
    }
    finally {
        invokeAdviceMethod(getJoinPointMatch(), null, null);
    }
}
  • <获取拦截器> 执行真正的逻辑方法
  • <After注解> 执行完After的切面逻辑,结束After注解执行
  • <Before注解> 执行完MethodBeforeAdviceInterceptor的proceed方法,结束Before注解执行
  • <Around注解> 执行完自定义切面逻辑中proceedingJoinPoint.proceed(),获得了真正逻辑的返回结果,再执行自定义切面逻辑的后半部分,然后结束Around注解执行
  • 所有切面执行完,返回结果