Spring source code analysis-AOP

foreword

AOP is a more commonly used function when we use Spring, let's take a look at the mystery today

@EnableAspectJAutoProxy

When AOP is used in a project, @EnableAspectJAutoProxy must be marked on a class, which means enabling AOP. What does this mean by enabling AOP?

@Aspect
@Component
@Slf4j
@EnableAspectJAutoProxy
public class AspectTest {
}
复制代码

Click on EnableAspectJAutoProxy and you will find that EnableAspectJAutoProxy imports the AspectJAutoProxyRegistrar class

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({AspectJAutoProxyRegistrar.class})
public @interface EnableAspectJAutoProxy {
    boolean proxyTargetClass() default false;
​
    boolean exposeProxy() default false;
}
复制代码

In a previous Spring article, I wrote that the @Import annotation can introduce three types of classes

  • ImportSelector type
  • ImportBeanDefinitionRegistrar type
  • common class

Regardless of the type, it is a way to register BeanDefinition. Here Import is ImportBeanDefinitionRegistrar, which registers the BeanDefinition of AnnotationAwareAspectJAutoProxyCreator.

@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
      BeanDefinitionRegistry registry, @Nullable Object source) {
​
   return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
复制代码

Looking at the inheritance diagram of the AnnotationAwareAspectJAutoProxyCreator class, you will find that it is only an annotation extension based on the original Spring-AOP. It should be noted that this class implements BeanPostProcessor. Students who are familiar with Spring source code should know what it means to implement this class. It means that AOP adds something to Spring's original Bean life cycle, and does not escape the cage of Spring.

image.png

some basics

Advice与Advisor

We often see Advice and Advisor. What is the difference between them?

Advice is a notification, Advisor is an enhancer, and each Advisor will hold an Advice

public interface Advisor {
  
   Advice EMPTY_ADVICE = new Advice() {};
   // 比如这个接口,可以获取Advisor持有的Advice
   Advice getAdvice();
   boolean isPerInstance();
​
}
复制代码
AopInfrastructureBean
// Spring内部的这个接口没有任何实现,只是一个标记接口,如果Spring中的类实现了这个接口,就会被标记为Spring的基础设施类
// 不会被自动代理
public interface AopInfrastructureBean {
​
}
​
// 在AbstractAutoProxyCreator这个类中,有一个方法,判断某个类需不需要被代理
// 如果是Advice、Pointcut、Advisor、AopInfrastructureBean的子类,则不需要被代理
protected boolean isInfrastructureClass(Class<?> beanClass) {
    boolean retVal = Advice.class.isAssignableFrom(beanClass) ||
        Pointcut.class.isAssignableFrom(beanClass) ||
        Advisor.class.isAssignableFrom(beanClass) ||
        AopInfrastructureBean.class.isAssignableFrom(beanClass);
    if (retVal && logger.isTraceEnabled()) {
      logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]");
    }
    return retVal;
}
复制代码
Pointcut

Pointcut作为Spring AOP最顶级的抽象,主要负责对系统相应Joinpoint的捕获,如果把Joinpoint比做数据,那么Pointcut就是查询条件,一个Pointcut可以对应多个Joinpoint。ClassFilter和MethodMatcher分别限定在不同级别上对于Joinpoint的匹配,ClassFilter是类级别,MethodMatcher是方法级别,使用AOP的同学应该都清楚,AOP主要支持方法级别的匹配,所以类级别的匹配功能较为简单

public interface Pointcut {
​
  ClassFilter getClassFilter();
  MethodMatcher getMethodMatcher();
  Pointcut TRUE = TruePointcut.INSTANCE;
​
}
​
​
public interface ClassFilter {
​
  // 给定的类是否匹配
  boolean matches(Class<?> clazz);
  ClassFilter TRUE = TrueClassFilter.INSTANCE;
​
}
​
​
public interface MethodMatcher {
​
  // 在这里有一个静态切入点和动态切入点的概念
  // 静态切入点:只进行一次检测
  // 动态切入点:每次切入都检测
  boolean matches(Method method, Class<?> targetClass);
  // 判断静态切入点和动态切入点的标志,return true表示动态
  boolean isRuntime();
  boolean matches(Method method, Class<?> targetClass, Object... args);
  MethodMatcher TRUE = TrueMethodMatcher.INSTANCE;
​
}
复制代码
IntroductionAdvisor

为AOP提供类级别的拦截

public interface IntroductionAdvisor extends Advisor, IntroductionInfo {
​
   ClassFilter getClassFilter();
​
   void validateInterfaces() throws IllegalArgumentException;
}
​
public interface IntroductionInfo {
  // 这个接口可以定义AOP适用的类,不适用的类,可以不进行AOP拦截
  Class<?>[] getInterfaces();
​
}
复制代码
PointcutAdvisor

为AOP提供方法级别的拦截

public interface PointcutAdvisor extends Advisor {
​
   Pointcut getPointcut();
​
}
复制代码

单纯看以上几个类,可能会很懵,下面是AOP过程中获取拦截器链的代码,结合这些代码感受一下AOP是如何对Advisor进行筛选的

@Override
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
      Advised config, Method method, @Nullable Class<?> targetClass) {
​
   AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
   Advisor[] advisors = config.getAdvisors();
   List<Object> interceptorList = new ArrayList<>(advisors.length);
   Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
   Boolean hasIntroductions = null;
​
   for (Advisor advisor : advisors) {
      // 如果advisor是PointcutAdvisor的实例
      if (advisor instanceof PointcutAdvisor) {
         PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
         // 如果是预先筛选过或者advisor适用于目标类
         if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
            // 进行方法级别的筛选
            MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
            boolean match;
            if (mm instanceof IntroductionAwareMethodMatcher) {
               if (hasIntroductions == null) {
                  hasIntroductions = hasMatchingIntroductions(advisors, actualClass);
               }
               match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);
            }
            else {
               match = mm.matches(method, actualClass);
            }
            if (match) {
               MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
               // 如果是动态切入点
               if (mm.isRuntime()) {
                  for (MethodInterceptor interceptor : interceptors) {
                     interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
                  }
               }
               else {
                  interceptorList.addAll(Arrays.asList(interceptors));
               }
            }
         }
      }
      // 如果advisor是IntroductionAdvisor的实例
      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;
}
复制代码
AdvisorAdapter

Advisor适配器,适配器这种类一般都是连接某两个类之间的桥梁,AdvisorAdapter则是连接Advisor与MethodInterceptor之间的桥梁,动态代理中,要执行指定的方法前,会执行一系列的拦截器,这些拦截器的单位是MethodInterceptor

public interface AdvisorAdapter {
​
   // 这个适配器是否支持这个Advice
   boolean supportsAdvice(Advice advice);
​
   // 将一个Advisor转换成MethodInterceptor
   MethodInterceptor getInterceptor(Advisor advisor);
​
}
复制代码

我们简单地看一个类,感受一个这个适配器是如何进行转换的

public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Serializable {
​
   private final List<AdvisorAdapter> adapters = new ArrayList<>(3);
   // 在构造器中就构建好了AdvisorAdapter的几个实现类
   public DefaultAdvisorAdapterRegistry() {
      registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
      registerAdvisorAdapter(new AfterReturningAdviceAdapter());
      registerAdvisorAdapter(new ThrowsAdviceAdapter());
   }
​
   @Override
   public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
      List<MethodInterceptor> interceptors = new ArrayList<>(3);
      Advice advice = advisor.getAdvice();
      // 如何Advice本身就是MethodInterceptor,不需要进行转换
      if (advice instanceof MethodInterceptor) {
         interceptors.add((MethodInterceptor) advice);
      }
      // 遍历adapters,先看这个AdvisorAdapter是否支持适配Advice,如果支持,则转换成MethodInterceptor
      for (AdvisorAdapter adapter : this.adapters) {
         if (adapter.supportsAdvice(advice)) {
            interceptors.add(adapter.getInterceptor(advisor));
         }
      }
      if (interceptors.isEmpty()) {
         throw new UnknownAdviceTypeException(advisor.getAdvice());
      }
      return interceptors.toArray(new MethodInterceptor[0]);
   }
​
   @Override
   public void registerAdvisorAdapter(AdvisorAdapter adapter) {
      this.adapters.add(adapter);
   }
​
}
复制代码

源码解析

上文讲过,AnnotationAwareAspectJAutoProxyCreator继承AbstractAutoProxyCreator且实现了BeanPostProcessor,在AbstractAutoProxyCreator类中,有两个方法是比较重要的,分别是postProcessBeforeInstantiation和postProcessAfterInitialization,先看看postProcessBeforeInstantiation

postProcessBeforeInstantiation

此方法主要是拦截一些不需要代理的类

public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
    implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
  @Override
  public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
    Object cacheKey = getCacheKey(beanClass, beanName);
    // 这里有两重判断
    // 1.如果beanName不为空
    // 2.如果这个bean不存在于targetSourcedBeans这个Map缓存中(当bean有自定义的TargetSource,会在这个方法中创建代理
    //   并且放到Map中
    if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
      // 如果bean存在于advisedBeans这个Map缓存中,直接返回
      // advisedBeans这个Map其实就是存在了哪些bean是不需要被代理的
      if (this.advisedBeans.containsKey(cacheKey)) {
        return null;
      }
      // isInfrastructureClass 这个方法会判断哪些bean是不需要被代理,shouldSkip 这个方法会判断该类是否需要被跳过
      if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return null;
      }
    }
​
    // 如果我们有自定义TargetSource,则在此处获取,并且创建代理
    // 一般不会自定义TargetSource
    TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
    if (targetSource != null) {
      if (StringUtils.hasLength(beanName)) {
        this.targetSourcedBeans.add(beanName);
      }
      Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
      Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
      this.proxyTypes.put(cacheKey, proxy.getClass());
      return proxy;
    }
​
    return null;
  }
}
复制代码

下面我们来详细看看shouldSkip这个方法,这个方法非常重要,在这个方法中,AOP所需要的Advisor都已经解析完毕

@Override
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
   // 找到候选的Advisor
   List<Advisor> candidateAdvisors = findCandidateAdvisors();
   for (Advisor advisor : candidateAdvisors) {
      if (advisor instanceof AspectJPointcutAdvisor &&
            ((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
         return true;
      }
   }
   return super.shouldSkip(beanClass, beanName);
}
复制代码
@Override
protected List<Advisor> findCandidateAdvisors() {
  // 根据规则找出实现了Advisor接口的bean
  List<Advisor> advisors = super.findCandidateAdvisors();
  // 找出标注了@Aspect注解的bean
  if (this.aspectJAdvisorsBuilder != null) {
    advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
  }
  return advisors;
}
复制代码
public List<Advisor> findAdvisorBeans() {
  // Determine list of advisor bean names, if not cached already.
  String[] advisorNames = this.cachedAdvisorBeanNames;
  if (advisorNames == null) {
    // 获取当前BeanFactory中所有实现了Advisor接口的bean的名称
    advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
      this.beanFactory, Advisor.class, true, false);
    this.cachedAdvisorBeanNames = advisorNames;
  }
  if (advisorNames.length == 0) {
    return new ArrayList<>();
  }
  // 对实现Advisor接口的bean的名称进行遍历
  List<Advisor> advisors = new ArrayList<>();
  for (String name : advisorNames) {
    // 提供了一个hook方法,可做适当扩展排除此name
    if (isEligibleBean(name)) {
      // 如果当前bean还在创建过程中,忽略
      if (this.beanFactory.isCurrentlyInCreation(name)) {
        if (logger.isTraceEnabled()) {
          logger.trace("Skipping currently created advisor '" + name + "'");
        }
      }
      else {
        try {
          // 将其放在结果中返回
          advisors.add(this.beanFactory.getBean(name, Advisor.class));
        }
        catch (BeanCreationException ex) {
          Throwable rootCause = ex.getMostSpecificCause();
          if (rootCause instanceof BeanCurrentlyInCreationException) {
            BeanCreationException bce = (BeanCreationException) rootCause;
            String bceBeanName = bce.getBeanName();
            if (bceBeanName != null && this.beanFactory.isCurrentlyInCreation(bceBeanName)) {
              if (logger.isTraceEnabled()) {
                logger.trace("Skipping advisor '" + name +
                             "' with dependency on currently created bean: " + ex.getMessage());
              }
              // Ignore: indicates a reference back to the bean we're trying to advise.
              // We want to find advisors other than the currently created bean itself.
              continue;
            }
          }
          throw ex;
        }
      }
    }
  }
  return advisors;
}
复制代码
public List<Advisor> buildAspectJAdvisors() {
  List<String> aspectNames = this.aspectBeanNames;
​
  if (aspectNames == null) {
    synchronized (this) {
      aspectNames = this.aspectBeanNames;
      if (aspectNames == null) {
        // 保存解析处理出来的Advisor对象
        List<Advisor> advisors = new ArrayList<>();
        aspectNames = new ArrayList<>();
        // 此处传入的是Object对象,代表获取容器中所有的组件的名称,十分消耗性能
        String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
          this.beanFactory, Object.class, true, false);
        // 遍历所有名称
        for (String beanName : beanNames) {
          if (!isEligibleBean(beanName)) {
            continue;
          }
          // 根据beanName获取Class
          Class<?> beanType = this.beanFactory.getType(beanName, false);
          if (beanType == null) {
            continue;
          }
          // 判断该Class是否为切面@Aspect
          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);
              // 获取Advisor
              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 {
              // Per target or per this.
              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;
      }
    }
  }
  // aspectNames不为空,说明之前已经解析过了,不需要重复解析,直接获取缓存中的数据
  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方法

​
@Override
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
  // 获取标记为@Aspect的Class
  Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
  // 获取标记为@Aspect的名称
  String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
  validate(aspectClass);
​
  // We need to wrap the MetadataAwareAspectInstanceFactory with a decorator
  // so that it will only instantiate once.
  MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
    new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
​
  List<Advisor> advisors = new ArrayList<>();
  // 获取切面类的所有方法,会排除掉@PointCut注解的方法
  for (Method method : getAdvisorMethods(aspectClass)) {
    // 解析切面中的方法
    Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, 0, aspectName);
    if (advisor != null) {
      advisors.add(advisor);
    }
  }
​
  // If it's a per target aspect, emit the dummy instantiating aspect.
  if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
    Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
    advisors.add(0, instantiationAdvisor);
  }
​
  // Find introduction fields.
  for (Field field : aspectClass.getDeclaredFields()) {
    Advisor advisor = getDeclareParentsAdvisor(field);
    if (advisor != null) {
      advisors.add(advisor);
    }
  }
​
  return advisors;
}
复制代码
​
public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,
                                                  Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,
                                                  MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
  // 当前的切点表达式
  this.declaredPointcut = declaredPointcut;
  // 切面的Class
  this.declaringClass = aspectJAdviceMethod.getDeclaringClass();
  // 切面的方法名称
  this.methodName = aspectJAdviceMethod.getName();
  // 切面的方法参数类型
  this.parameterTypes = aspectJAdviceMethod.getParameterTypes();
  // 切面的方法
  this.aspectJAdviceMethod = aspectJAdviceMethod;
  this.aspectJAdvisorFactory = aspectJAdvisorFactory;
  this.aspectInstanceFactory = aspectInstanceFactory;
  // 切面的顺序
  this.declarationOrder = declarationOrder;
  // 切面的名称
  this.aspectName = 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 {
    this.pointcut = this.declaredPointcut;
    this.lazy = false;
    // 构造Advice对象
    this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
  }
}
复制代码
​
​
@Override
@Nullable
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
                        MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
​
  Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
  validate(candidateAspectClass);
​
  AspectJAnnotation<?> aspectJAnnotation =
    AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
  if (aspectJAnnotation == null) {
    return null;
  }
​
  // If we get here, we know we have an AspectJ method.
  // Check that it's an AspectJ-annotated class
  if (!isAspect(candidateAspectClass)) {
    throw new AopConfigException("Advice must be declared inside an aspect type: " +
                                 "Offending method '" + candidateAdviceMethod + "' in class [" +
                                 candidateAspectClass.getName() + "]");
  }
​
  if (logger.isDebugEnabled()) {
    logger.debug("Found AspectJ method: " + candidateAdviceMethod);
  }
​
  AbstractAspectJAdvice springAdvice;
  // 根据注解生成相应的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);
  }
​
  // 配置该Advice
  // 设置切面名称
  springAdvice.setAspectName(aspectName);
  // 设置切面的执行优先级
  springAdvice.setDeclarationOrder(declarationOrder);
  String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
  if (argNames != null) {
    // 设置方法参数
    springAdvice.setArgumentNamesFromStringArray(argNames);
  }
  springAdvice.calculateArgumentBindings();
​
  return springAdvice;
}
复制代码
postProcessAfterInitialization

经过postProcessBeforeInstantiation的处理,所有不需要被代理的类都已经被屏蔽了,Advisor也已经解析完毕,万事具备,只差生成代理对象了

@Override
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;
}
复制代码
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;
  }
  // 如果是基础设施类,或是应该跳过的类,则不应该生成代理,直接返回bean
  if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
    this.advisedBeans.put(cacheKey, Boolean.FALSE);
    return bean;
  }
​
  // 如果specificInterceptors不为空,则创建对应的代理对象
  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;
}
复制代码
@Override
@Nullable
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();
}
​
​
​
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
  // 找到IOC容器中所有实现了Advisor接口的bean
  List<Advisor> candidateAdvisors = findCandidateAdvisors();
  // 判断找到的Advisor接口能否应用到当前的bean上
  List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
  // 对Advisor进行排序
  extendAdvisors(eligibleAdvisors);
  if (!eligibleAdvisors.isEmpty()) {
    eligibleAdvisors = sortAdvisors(eligibleAdvisors);
  }
  return eligibleAdvisors;
}
复制代码
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
   // 这里有一个比较关键的判断,config.isProxyTargetClass() 默认为false
   // 假如为true,则表示强制使用cglib代理
   // 所以有些面试官会问,哪些类会用cglib代理,哪些类会用jdk动态代理,我们一般回答类实现了接口会用jdk动态代理
   // 没有接口会用cglib代理,其实回答得并不是很全面
   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)) {
         return new JdkDynamicAopProxy(config);
      }
      // cglib代理
      return new ObjenesisCglibAopProxy(config);
   }
   else {
      // jdk动态代理
      return new JdkDynamicAopProxy(config);
   }
}
复制代码
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
   if (logger.isTraceEnabled()) {
      logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
   }
   // 创建代理对象
   return Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this);
}
复制代码
public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
   Assert.notNull(config, "AdvisedSupport must not be null");
   // 此处有两个判断
   // 1.advisors是否为空,前面我们讲过,advisor是advice的容器,如果advisor为空,表示没有对应的切面
   // 2,targetSource是否为空,表示代理的来源不能为空
   // 这两个判断的意思是,创建代理时,如果没有类的来源或者没有对应的切面,没有创建代理的意义
   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);
   // 判断equal和hashCode方法是否被重写
   findDefinedEqualsAndHashCodeMethods(this.proxiedInterfaces);
}
复制代码
// 这个方法比较有意思,我们都知道equal和hashCode方法会经常被集合框架用到,用于判断key是否重复,是一个比较高频的操作
// 所以AOP会特别地缓存下来此接口是否重写了equal和hashCode方法
private void findDefinedEqualsAndHashCodeMethods(Class<?>[] proxiedInterfaces) {
   for (Class<?> proxiedInterface : proxiedInterfaces) {
      Method[] methods = proxiedInterface.getDeclaredMethods();
      for (Method method : methods) {
         // 判断equal是否被重写
         if (AopUtils.isEqualsMethod(method)) {
            this.equalsDefined = true;
         }
         // 判断hashCode方法是否被重写
         if (AopUtils.isHashCodeMethod(method)) {
            this.hashCodeDefined = true;
         }
         // 若是两个方法都被重写,就不继续往下找了
         if (this.equalsDefined && this.hashCodeDefined) {
            return;
         }
      }
   }
}
复制代码
方法调用实现拦截
@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 {
      // 如果是equal方法不需要代理
      if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
         return equals(args[0]);
      }
      // 如果是hashCode方法不需要代理
      else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
         return hashCode();
      }
      .....
​
      Object retVal;
      // 将代理对象暴露在线程变量中
      if (this.advised.exposeProxy) {
         oldProxy = AopContext.setCurrentProxy(proxy);
         setProxyContext = true;
      }
​
      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 {
         // 如果拦截器链不为空,则使用到了责任链设计模式
         MethodInvocation invocation =
               new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
         // 执行拦截器链
         retVal = invocation.proceed();
      }
​
      // 获取方法返回值类型
      Class<?> returnType = method.getReturnType();
      // 如果返回值为this,则将代理对象proxy返回
      if (retVal != null && retVal == target &&
            returnType != Object.class && returnType.isInstance(proxy) &&
            !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
         retVal = proxy;
      }
      // 如果返回值类型为基础类型,比如int,但是retVal又为null,抛出异常
      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);
      }
   }
}
复制代码
@Override
@Nullable
public Object proceed() throws Throwable {
   // 下标从-1开始,直到最后一个拦截器,执行目标方法
   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 {
      return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
   }
}
复制代码

参考资料

极客时间

www.tianxiaobo.com/2018/06/20/…

www.cnblogs.com/toby-xu/p/1…

Guess you like

Origin juejin.im/post/7079719785772089380