Spring源码解析-AOP

前言

AOP是我们使用Spring时较为常用的功能,今天让我们来看看其中的玄机

@EnableAspectJAutoProxy

项目中使用AOP的时候,都必须在某个类上标注@EnableAspectJAutoProxy,代表开启AOP,这个开启AOP是什么意思呢?

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

点击进去EnableAspectJAutoProxy,会发现EnableAspectJAutoProxy import 了AspectJAutoProxyRegistrar类

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

在之前的Spring文章中,我曾写过,@Import这个注解可以引入三种类型的类

  • ImportSelector类型
  • ImportBeanDefinitionRegistrar类型
  • 普通类

不管哪种类型,都是注册BeanDefinition的一种方式,此处Import的是ImportBeanDefinitionRegistrar,这个类注册了AnnotationAwareAspectJAutoProxyCreator这个BeanDefinition

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

看看AnnotationAwareAspectJAutoProxyCreator这个类的继承图,会发现它只是在原有Spring-AOP的基础上做了注解方面的扩展。需要特别注意的是,该类实现了BeanPostProcessor,对Spring源码比较熟悉的同学应该知道实现这个类意味着什么,说明AOP是在Spring原有Bean生命周期上加东西,并没有逃脱Spring的牢笼

image.png

一些基础知识

Advice与Advisor

我们经常会看到Advice、Advisor,他们有什么区别呢?

Advice是通知,Advisor是增强器,每个Advisor都会持有一个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…

猜你喜欢

转载自juejin.im/post/7079719785772089380