Spring源码解析-AOP

AOP源码解析

动态代理

参考:https://blog.csdn.net/cblstc/article/details/79651136

AOP的一些概念

AOP的概念特别抽象,还是得通过代码去理解。

public class AopConfig {

    // config包下的类和子类
    @Pointcut(value = "execution(* com.cbl.aop.config..*.*(..))")
    public void pointcut() {}

    @Before(value = "pointcut()")
    public void beforeOp() {
        System.out.println("BeforeOp...");
    }

    @After(value = "pointcut()")
    public void afterOp() {
        System.out.println("AfterOp...");
    }
}

切点:我们可以通过@Pointcut定义切点表达式,如上面的例子,表示该包下的所有类和方法都会被拦截,拦截后就可以加上我们自定义的一些逻辑了,比如在方法执行前、方法执行后打印日志。

增强:比如通过@Before去定义被拦截的方法执行前需要做什么事。

切面:切面=切点+增强,我理解@Before定义了一个切面,@After也定义了一个切面,它们都包括方法和表达式。

个人理解:Aspect包含多个Advisor,每个Advisor=Pointcut+Advice

AOP入口

ConfigurationClassPostProcessor#processConfigBeanDefinitions

this.reader.loadBeanDefinitions(configClasses);

然后走loadBeanDefinitionsForConfigurationClass,此处加载一些注册类,如AOP入口类的注册方法的调用

loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());

此时如果registrar是AspectJAutoProxyRegistrar类型时,就会调用该类的registerBeanDefinitions方法。

private void loadBeanDefinitionsFromRegistrars(Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> registrars) {
   registrars.forEach((registrar, metadata) ->
         registrar.registerBeanDefinitions(metadata, this.registry, this.importBeanNameGenerator));
}

我们再看下开启aop的注解,@EnableAspectJAutoProxy,它import了AspectJAutoProxyRegistrar类,这个类就是aop的入口类。

proxyTargetClass=true,cglib;proxyTargetClass=false且bean实现了接口,jdk代理,其余情况cglib

@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
   boolean proxyTargetClass() default false;

   boolean exposeProxy() default false;
}

从前面可知,registerBeanDefinitions会被调用

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {

   @Override
   public void registerBeanDefinitions(
         AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

      AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);

      AnnotationAttributes enableAspectJAutoProxy =
            AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
      if (enableAspectJAutoProxy != null) {
         if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
            AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
         }
         if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
            AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
         }
      }
   }

}

接着调用AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary,把AnnotationAwareAspectJAutoProxyCreator这个Bean注入到容器中

public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
      BeanDefinitionRegistry registry, @Nullable Object source) {

   return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}

private static BeanDefinition registerOrEscalateApcAsRequired(
			Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
	  // ....
		RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
		beanDefinition.setSource(source);
		beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
		beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
    // BeanFactory.registerBeanDefinition
		registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
		return beanDefinition;
	}

小结:@EnableAspectJAutoProxy的作用主要是把AnnotationAwareAspectJAutoProxyCreator注入到ioc容器中。

AOP什么时候生成代理

AbstractAutowireCapableBeanFactory#doCreateBean,Bean实例化和依赖注入之后,执行initializeBean方法,再执行applyBeanPostProcessorsAfterInitialization方法去生成bean的代理。

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
      throws BeanCreationException {

   Object exposedObject = bean;
   try {
      // 依赖注入
      populateBean(beanName, mbd, instanceWrapper);
      // 依赖注入后调用
      exposedObject = initializeBean(beanName, exposedObject, mbd);
   }
  // ...

   return exposedObject;
}

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
   // ...
   if (mbd == null || !mbd.isSynthetic()) {
      //这个地方可能生出代理实例,是aop的入口
      wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
   }

   return wrappedBean;
}

遍历所有BeanPostProcessors,调用每个BeanPostProcessors的postProcessAfterInitialization方法

public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
      throws BeansException {

   Object result = existingBean;
   for (BeanPostProcessor processor : getBeanPostProcessors()) {
     // 初始化完成后调用postProcessAfterInitialization
      Object current = processor.postProcessAfterInitialization(result, beanName);
      if (current == null) {
         return result;
      }
      result = current;
   }
   return result;
}

我们重点看下AnnotationAwareAspectJAutoProxyCreator这个Bean,这个Bean在@EnableAspectJAutoProxy时注入到ioc容器了。查看它的postProcessAfterInitialization方法,其实是它的父类 AbstractAutoProxyCreator#postProcessAfterInitialization。接着走wrapIfNecessary进行Bean的增强

public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
   if (bean != null) {
      Object cacheKey = getCacheKey(bean.getClass(), beanName);
      if (this.earlyProxyReferences.remove(cacheKey) != bean) {
        // 走这里进行bean的装配
         return wrapIfNecessary(bean, beanName, cacheKey);
      }
   }
   return bean;
}
AOP如何生成代理

猜想:首先拿到所有的AOP配置类,即扫描所有@Aspect修饰的类。然后遍历AOP配置类,把类的所有方法(除了@Pointcut修饰的方法)拿出来,此时的方法可能是切面方法,也可能不是。那么如果是切面方法,就封装成Advisor实例(切点+增强Advice)

Todo: AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation#applyBeanPostProcessorsBeforeInstantiation#AbstractAutoProxyCreator#postProcessBeforeInstantiation#shouldSkip

接下来调用wrapIfNecessary进行bean的装配

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
   // ...

   // 创建当前bean的代理,如果这个bean有advice的话
   Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
   //如果有切面,则生成该bean的代理
   if (specificInterceptors != DO_NOT_PROXY) {
      this.advisedBeans.put(cacheKey, Boolean.TRUE);
      //把被代理对象bean实例封装到SingletonTargetSource对象中
      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;
}

创建当前bean的代理

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

找到合格的切面,主要是两个步骤:

1、找到所有候选的Advisor;

2、在这些候选的Advisor中找到满足要求的Advisor,即Advisor是否作用于该bean,通过对表达式的解析可实现。

protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
   // 找到候选的切面,就是找到所有@Aspect修饰的类,把类里面的增强方法封装成Advisor
   List<Advisor> candidateAdvisors = findCandidateAdvisors();
   // 判断候选的切面是否作用在当前beanClass上面
   List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
   // 针对@Aspect注解切面添加了一个默认的切面 DefaultPointcutAdvisor
   extendAdvisors(eligibleAdvisors);
   if (!eligibleAdvisors.isEmpty()) {
      //对有@Order@Priority进行排序
      eligibleAdvisors = sortAdvisors(eligibleAdvisors);
   }
   return eligibleAdvisors;
}
找到候选的切面
protected List<Advisor> findCandidateAdvisors() {
   // Add all the Spring advisors found according to superclass rules.
   //找到所有的Advisor
   List<Advisor> advisors = super.findCandidateAdvisors();
   // Build Advisors for all AspectJ aspects in the bean factory.
   //主要看这里,创建候选的切面  对@Aspect注解的类进行处理
   if (this.aspectJAdvisorsBuilder != null) {
      advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
   }
   return advisors;
}
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<>();
            //获取spring容器中的所有bean的名称BeanName
            String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                  this.beanFactory, Object.class, true, false);
            for (String beanName : beanNames) {
               // ...
               //判断类上是否有@Aspect注解
               if (this.advisorFactory.isAspect(beanType)) {
                 // 走到这里,说明是AOP配置类(@Aspect修饰的)
                  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);
                  }
                  // ...
               }
            }
            this.aspectBeanNames = aspectNames;
            return advisors;
         }
      }
   }
// ...
   return advisors;
}
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<>();
   for (Method method : getAdvisorMethods(aspectClass)) {
     // 遍历所有非@Pointcut的方法,调用getAdvisor获取Advisor
      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()) {
      //判断属性上是否有DeclareParents注解,如果有返回切面
      Advisor advisor = getDeclareParentsAdvisor(field);
      if (advisor != null) {
         advisors.add(advisor);
      }
   }

   return advisors;
}

调用getAdvisorMethods,这个方法主要是拿到带有@Aspect注解的类中的所有方法(除了@Pointcut修饰的方法)

private List<Method> getAdvisorMethods(Class<?> aspectClass) {
   final List<Method> methods = new ArrayList<>();
   ReflectionUtils.doWithMethods(aspectClass, method -> {
      // 排除@Pointcut修饰的方法
      if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) {
         methods.add(method);
      }
   }, ReflectionUtils.USER_DECLARED_METHODS);
   if (methods.size() > 1) {
      //按照注解先后顺序+自然顺序排序
      methods.sort(METHOD_COMPARATOR);
   }
   return methods;
}

获取Advisor

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

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

   //获取pointCut对象,最重要的是从注解中获取表达式
   AspectJExpressionPointcut expressionPointcut = getPointcut(
         candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
   if (expressionPointcut == null) {
      return null;
   }

   // 创建Advisor切面类,这才是真正的切面类,一个切面类里面肯定要有1、pointCut 2、advice
   // 这里pointCut是expressionPointcut, advice增强方法是candidateAdviceMethod
   return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
         this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}

获取Pointcut对象

private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
   //从候选的增强方法里面 candidateAdviceMethod  找有有注解
   //Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class
   //并把注解信息封装成AspectJAnnotation对象
   AspectJAnnotation<?> aspectJAnnotation =
         AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
   if (aspectJAnnotation == null) {
      return null;
   }

   //创建一个PointCut类,并且把前面从注解里面解析的表达式设置进去
   AspectJExpressionPointcut ajexp =
         new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class<?>[0]);
   ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
   if (this.beanFactory != null) {
      ajexp.setBeanFactory(this.beanFactory);
   }
   return ajexp;
}

我们知道pointcut有两种定义方式,一种是定义@Pointcut void pc(),然后@Before(“pc()”),另一种是直接在@Before上写表达式,所以收集Pointcut的过程即收集Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class的过程

protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {
   //Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class
   for (Class<?> clazz : ASPECTJ_ANNOTATION_CLASSES) {
      //找到Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class
      //注解的方法,并且把注解里面的信息封装成AspectJAnnotation对象
      AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class<Annotation>) clazz);
      if (foundAnnotation != null) {
         return foundAnnotation;
      }
   }
   return null;
}
private static <A extends Annotation> AspectJAnnotation<A> findAnnotation(Method method, Class<A> toLookFor) {
   A result = AnnotationUtils.findAnnotation(method, toLookFor);
   if (result != null) {
      //把注解里面的信息解析出来,然后包装成AspectJAnnotation对象
      return new AspectJAnnotation<>(result);
   }
   else {
      return null;
   }
}

创建Advisor实例,需要重点看下。

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

  // 一些赋值操作
   this.declaredPointcut = declaredPointcut;
   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;

   //...
   else {
      // A singleton aspect.
      this.pointcut = this.declaredPointcut;
      this.lazy = false;
      //这个方法重点看看,创建advice对象
      this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
   }
}
private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) {
   //创建Advice对象
   Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut,
         this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
   return (advice != null ? advice : EMPTY_ADVICE);
}
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
      MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {

   //获取有@Aspect注解的类
   Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
   validate(candidateAspectClass);

   //找到candidateAdviceMethod方法上面的注解,并且包装成AspectJAnnotation对象,这个对象中就有注解类型
   AspectJAnnotation<?> aspectJAnnotation =
         AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
   if (aspectJAnnotation == null) {
      return null;
   }
  
  // ...

   AbstractAspectJAdvice springAdvice;

   //根据不同的注解类型创建不同的advice类实例
   switch (aspectJAnnotation.getAnnotationType()) {
      case AtPointcut:
         if (logger.isDebugEnabled()) {
            logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
         }
         return null;
      case AtAround:
         //实现了MethodInterceptor接口
         springAdvice = new AspectJAroundAdvice(
               candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
         break;
      case AtBefore:
         //实现了MethodBeforeAdvice接口,没有实现MethodInterceptor接口
         springAdvice = new AspectJMethodBeforeAdvice(
               candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
         break;
      case AtAfter:
         //实现了MethodInterceptor接口
         springAdvice = new AspectJAfterAdvice(
               candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
         break;
      case AtAfterReturning:
         //实现了AfterReturningAdvice接口,没有实现MethodInterceptor接口
         springAdvice = new AspectJAfterReturningAdvice(
               candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
         AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
         if (StringUtils.hasText(afterReturningAnnotation.returning())) {
            springAdvice.setReturningName(afterReturningAnnotation.returning());
         }
         break;
      case AtAfterThrowing:
         //实现了MethodInterceptor接口
         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);
   }

   // Now to configure the advice...
   springAdvice.setAspectName(aspectName);
   springAdvice.setDeclarationOrder(declarationOrder);
   //获取注解中的argNames属性参数名称
   String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
   if (argNames != null) {
      springAdvice.setArgumentNamesFromStringArray(argNames);
   }
   //计算argNames和类型的对应关系
   springAdvice.calculateArgumentBindings();

   return springAdvice;
}
找到合格的切面
protected List<Advisor> findAdvisorsThatCanApply(
      List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {

   ProxyCreationContext.setCurrentProxiedBeanName(beanName);
   try {
      //看看当前类是否在这些切面的pointCut中..调用类和方法的match过程
      return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
   }
   finally {
      ProxyCreationContext.setCurrentProxiedBeanName(null);
   }
}
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();
   //调用pointCut中的ClassFilter 和methodMatcher的match方法的过程
   for (Advisor candidate : candidateAdvisors) {
      if (candidate instanceof IntroductionAdvisor) {
         // already processed
         continue;
      }
      if (canApply(candidate, clazz, hasIntroductions)) {
         eligibleAdvisors.add(candidate);
      }
   }
   return eligibleAdvisors;
}

是否匹配

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;
   }
}
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
   Assert.notNull(pc, "Pointcut must not be null");
   //调用ClassFilter的matches方法,判断类是否匹配
   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);
      for (Method method : methods) {
         if (introductionAwareMethodMatcher != null ?
               introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
               methodMatcher.matches(method, targetClass)) {
            return true;
         }
      }
   }

   return false;
}
public boolean matches(Class<?> targetClass) {
   //这里会根据@Around("pc1()")配置中的pc1找到pc1方法从而找到真正的pointCut表达式
   PointcutExpression pointcutExpression = obtainPointcutExpression();
   try {
      try {
         //匹配targetClass是否在表达式中
         return pointcutExpression.couldMatchJoinPointsInType(targetClass);
      }
      catch (ReflectionWorldException ex) {
         logger.debug("PointcutExpression matching rejected target class - trying fallback expression", ex);
         // Actually this is still a "maybe" - treat the pointcut as dynamic if we don't know enough yet
         PointcutExpression fallbackExpression = getFallbackPointcutExpression(targetClass);
         if (fallbackExpression != null) {
            return fallbackExpression.couldMatchJoinPointsInType(targetClass);
         }
      }
   }
   catch (Throwable ex) {
      logger.debug("PointcutExpression matching rejected target class", ex);
   }
   return false;
}
private PointcutExpression obtainPointcutExpression() {
   if (getExpression() == null) {
      throw new IllegalStateException("Must set property 'expression' before attempting to match");
   }
   if (this.pointcutExpression == null) {
      this.pointcutClassLoader = determinePointcutClassLoader();
      this.pointcutExpression = buildPointcutExpression(this.pointcutClassLoader);
   }
   return this.pointcutExpression;
}
创建代理

当我们收集到bean的切面后,需要走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();
   //把AnnotationAwareAspectJAutoProxyCreator中的某些属性copy到proxyFactory中
   proxyFactory.copyFrom(this);

   if (!proxyFactory.isProxyTargetClass()) {
     // ProxyTargetClass=true,cglib;ProxyTargetClass=false&&bean没有接口,jdk代理
      if (shouldProxyTargetClass(beanClass, beanName)) {
         proxyFactory.setProxyTargetClass(true);
      }
      else {
         evaluateProxyInterfaces(beanClass, proxyFactory);
      }
   }
   //组装advisor
   Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
   //把advisor加入到proxyFactory
   proxyFactory.addAdvisors(advisors);
   //把targetSource对象加入到proxyFactory
   proxyFactory.setTargetSource(targetSource);
   customizeProxyFactory(proxyFactory);

   proxyFactory.setFrozen(this.freezeProxy);
   if (advisorsPreFiltered()) {
      proxyFactory.setPreFiltered(true);
   }
   //获取代理对象
   return proxyFactory.getProxy(getProxyClassLoader());
}

重新封装Advisor,会找到自定义的MethodInterceptor封装为Advisor对象

protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) {
   // Handle prototypes correctly...
   //设置自定义的MethodInterceptor 和 Advice
   Advisor[] commonInterceptors = resolveInterceptorNames();

   List<Object> allInterceptors = new ArrayList<>();
   if (specificInterceptors != null) {
      allInterceptors.addAll(Arrays.asList(specificInterceptors));
      if (commonInterceptors.length > 0) {
         if (this.applyCommonInterceptorsFirst) {
            allInterceptors.addAll(0, Arrays.asList(commonInterceptors));
         }
         else {
            allInterceptors.addAll(Arrays.asList(commonInterceptors));
         }
      }
   }
  //...

   Advisor[] advisors = new Advisor[allInterceptors.size()];
   for (int i = 0; i < allInterceptors.size(); i++) {
      advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
   }
   return advisors;
}

获取代理对象,根据 proxyTargetClass 参数和是否实现接口来判断是采用 jdk 代理还是 cglib 代理

Jdk: org.springframework.aop.framework.JdkDynamicAopProxy#getProxy(java.lang.ClassLoader)

cglib: org.springframework.aop.framework.CglibAopProxy#getProxy(java.lang.ClassLoader)

public Object getProxy(@Nullable ClassLoader classLoader) {
   return createAopProxy().getProxy(classLoader);
}

jdk

public Object getProxy(@Nullable ClassLoader classLoader) {
   if (logger.isTraceEnabled()) {
      logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
   }
   Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
   findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
  // 生成代理,接下来会走invoke方法
   return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}

cglib

public Object getProxy(@Nullable ClassLoader classLoader) {
   if (logger.isTraceEnabled()) {
      logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
   }

   try {
      Class<?> rootClass = this.advised.getTargetClass();
      Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");

      Class<?> proxySuperClass = rootClass;
      if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
         proxySuperClass = rootClass.getSuperclass();
         Class<?>[] additionalInterfaces = rootClass.getInterfaces();
         for (Class<?> additionalInterface : additionalInterfaces) {
            this.advised.addInterface(additionalInterface);
         }
      }

      // Validate the class, writing log messages as necessary.
      validateClassIfNecessary(proxySuperClass, classLoader);

      // Configure CGLIB Enhancer...
      Enhancer enhancer = createEnhancer();
      if (classLoader != null) {
         enhancer.setClassLoader(classLoader);
         if (classLoader instanceof SmartClassLoader &&
               ((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
            enhancer.setUseCache(false);
         }
      }
      enhancer.setSuperclass(proxySuperClass);
      enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
      enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
      enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));

      Callback[] callbacks = getCallbacks(rootClass);
      Class<?>[] types = new Class<?>[callbacks.length];
      for (int x = 0; x < types.length; x++) {
         types[x] = callbacks[x].getClass();
      }
      // fixedInterceptorMap only populated at this point, after getCallbacks call above
      enhancer.setCallbackFilter(new ProxyCallbackFilter(
            this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
      enhancer.setCallbackTypes(types);

      // Generate the proxy class and create a proxy instance.
      return createProxyClassAndInstance(enhancer, callbacks);
   }
   catch (CodeGenerationException | IllegalArgumentException ex) {
      throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
            ": Common causes of this problem include using a final class or a non-visible class",
            ex);
   }
   catch (Throwable ex) {
      // TargetSource.getTarget() failed
      throw new AopConfigException("Unexpected AOP exception", ex);
   }
}
代理类的调用

jdk动态代理原理:生成的代理类有被代理类的方法,方法内容为this.h.invoke,这个h即我们实现的InvocationHandler类,这就是我们需要实现InvocationHandler的原因。

JdkDynamicAopProxy实现了InvocationHandler,当jdk动态代理时会调用JdkDynamicAopProxy.#invoke方法

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
   Object oldProxy = null;
   boolean setProxyContext = false;

   //从代理工厂中拿到TargetSource对象,该对象包装了被代理实例bean
   TargetSource targetSource = this.advised.targetSource;
   Object target = null;

   try {
      //被代理对象的equals方法和hashCode方法是不能被代理的,不会走切面
      if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
         // The target does not implement the equals(Object) method itself.
         return equals(args[0]);
      }
      else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
         // The target does not implement the hashCode() method itself.
         return hashCode();
      }
      else if (method.getDeclaringClass() == DecoratingProxy.class) {
         // There is only getDecoratedClass() declared -> dispatch to proxy config.
         return AopProxyUtils.ultimateTargetClass(this.advised);
      }
      else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
            method.getDeclaringClass().isAssignableFrom(Advised.class)) {
         // Service invocations on ProxyConfig with the proxy config...
         return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
      }

      Object retVal;

      //如果该属性设置为true,则把代理对象设置到ThreadLocal中
      if (this.advised.exposeProxy) {
         // Make invocation available if necessary.
         oldProxy = AopContext.setCurrentProxy(proxy);
         setProxyContext = true;
      }

      // Get as late as possible to minimize the time we "own" the target,
      // in case it comes from a pool.
      //这个target就是被代理实例
      target = targetSource.getTarget();
      Class<?> targetClass = (target != null ? target.getClass() : null);

      // Get the interception chain for this method.
      //从代理工厂中拿过滤器链 Object是一个MethodInterceptor类型的对象,其实就是一个advice对象
      List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

      // Check whether we have any advice. If we don't, we can fallback on direct
      // reflective invocation of the target, and avoid creating a MethodInvocation.
      //如果该方法没有执行链,则说明这个方法不需要被拦截,则直接反射调用
      if (chain.isEmpty()) {
         // We can skip creating a MethodInvocation: just invoke the target directly
         // Note that the final invoker must be an InvokerInterceptor so we know it does
         // nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
         Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
         retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
      }
      else {
         // We need to create a method invocation...
         MethodInvocation invocation =
               new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
         // Proceed to the joinpoint through the interceptor chain.
        // 走这里进行链式调用
         retVal = invocation.proceed();
      }

      // Massage return value if necessary.
      Class<?> returnType = method.getReturnType();
      if (retVal != null && retVal == target &&
            returnType != Object.class && returnType.isInstance(proxy) &&
            !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
         // Special case: it returned "this" and the return type of the method
         // is type-compatible. Note that we can't help if the target sets
         // a reference to itself in another returned object.
         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()) {
         // Must have come from TargetSource.
         targetSource.releaseTarget(target);
      }
      if (setProxyContext) {
         // Restore old proxy.
         AopContext.setCurrentProxy(oldProxy);
      }
   }
}

拿到过滤器链

public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) {
   MethodCacheKey cacheKey = new MethodCacheKey(method);
   List<Object> cached = this.methodCache.get(cacheKey);
   if (cached == null) {
      //获取过滤器链
      cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
            this, method, targetClass);
      this.methodCache.put(cacheKey, cached);
   }
   return cached;
}
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
      Advised config, Method method, @Nullable Class<?> targetClass) {

   // This is somewhat tricky... We have to process introductions first,
   // but we need to preserve order in the ultimate list.
   AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
   //从代理工厂中获得该被代理类的所有切面advisor,config就是代理工厂对象
   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) {
      //大部分走这里
      if (advisor instanceof PointcutAdvisor) {
         // Add it conditionally.
         PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
         //如果切面的pointCut和被代理对象是匹配的,说明是切面要拦截的对象..先进行类匹配
         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) {
               //获取到切面advisor中的advice,并且包装成MethodInterceptor类型的对象
               MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
               if (mm.isRuntime()) {
                  // Creating a new object instance in the getInterceptors() method
                  // isn't a problem as we normally cache created chains.
                  for (MethodInterceptor interceptor : interceptors) {
                     interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
                  }
               }
               else {
                  interceptorList.addAll(Arrays.asList(interceptors));
               }
            }
         }
      }
      //如果是引介切面
      else if (advisor instanceof IntroductionAdvisor) {
         IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
         if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
            Interceptor[] interceptors = registry.getInterceptors(advisor);
            interceptorList.addAll(Arrays.asList(interceptors));
         }
      }
      else {
         Interceptor[] interceptors = registry.getInterceptors(advisor);
         interceptorList.addAll(Arrays.asList(interceptors));
      }
   }

   return interceptorList;
}
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
   List<MethodInterceptor> interceptors = new ArrayList<>(3);
   Advice advice = advisor.getAdvice();
  // 如果是MethodInterceptor类型,如AspectJAroundAdvice 、 AspectJAfterAdvice 、 AspectJAfterThrowingAdvice,直接添加
   if (advice instanceof MethodInterceptor) {
      interceptors.add((MethodInterceptor) advice);
   }
  // 如果是MethodBeforeAdviceAdapter、AfterReturningAdviceAdapter、ThrowsAdviceAdapter,则需要包装成interceptor
   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]);
}

链式调用

ReflectiveMethodInvocation#proceed

public Object proceed() throws Throwable {
   // We start with an index of -1 and increment early.
   if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
     // 当所有拦截器执行完毕,走invokeJoinpoint,这里会调用代理类的方法
      return invokeJoinpoint();
   }

  // currentInterceptorIndex初始值-1,这里根据下标找到拦截器
   Object interceptorOrInterceptionAdvice =
         this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
   if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
      // Evaluate dynamic method matcher here: static part will already have
      // been evaluated and found to match.
      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 {
         // Dynamic matching failed.
         // Skip this interceptor and invoke the next in the chain.
         return proceed();
      }
   }
   else {
     // 调用拦截器的invoke方法
      // It's an interceptor, so we just invoke it: The pointcut will have
      // been evaluated statically before this object was constructed.
      return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
   }
}

前置增强:MethodBeforeAdviceInterceptor#invoke

public Object invoke(MethodInvocation mi) throws Throwable {
   this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis()); // 前置增强,即会调用增强方法
   return mi.proceed(); // 继续执行拦截器
}

后置增强:AspectJAfterAdvice#invoke

public Object invoke(MethodInvocation mi) throws Throwable {
   try {
      return mi.proceed();  // 继续执行拦截器
   }
   finally {
      invokeAdviceMethod(getJoinPointMatch(), null, null); // 调用后置方法
   }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值