Spring AOP 源码解析

Spring版本是5.1.x

文章目录

  • @EnableAspectJAutoProxy
  • AnnotationAwareAspectJAutoProxyCreator
    • 判断是否需要生成代理
    • 获取所有的advisor
      • 构建advisor
  • 筛选出匹配的advisor
  • 创建代理
  • 调用方法执行增强逻辑
    • Advice转换为MethodInterceptor
    • 执行拦截器链
      • ExposeInvocationInterceptor
      • AspectJAfterThrowingAdvice
      • AfterReturningAdviceInterceptor
      • AspectJAfterAdvice
      • AspectJAroundAdvice
      • MethodBeforeAdviceInterceptor

@EnableAspectJAutoProxy

aop入口是@EnableAspectJAutoProxy注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {

	/**
	 * 决定创建代理的方式,默认false,表示根据类是否实现接口来判断是通过jdk代理还是cglib代理;
     * true则表示通过cglib生成代理
	 */
	boolean proxyTargetClass() default false;

	/**
	 * 控制代理的暴露方式,解决内部调用不能使用代理的场景,true则会将代理对象放到ThreadLocal中,通过
     * AopContext可以获取到该代理对象
	 */
	boolean exposeProxy() default false;

}

该注解的核心是@Import(AspectJAutoProxyRegistrar.class),在容器初始化过程中,invokeBeanFactoryPostProcessors(beanFactory)方法会调用AspectJAutoProxyRegistrar中的registerBeanDefinitions方法,向容器中注入AnnotationAwareAspectJAutoProxyCreator类型的bean定义。

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {

	/**
	 * Register, escalate, and configure the AspectJ auto proxy creator based on the value
	 * of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing
	 * {@code @Configuration} class.
	 */
	@Override
	public void registerBeanDefinitions(
			AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
		// 向容器中注入AnnotationAwareAspectJAutoProxyCreator的beanDifinition
		AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);

		AnnotationAttributes enableAspectJAutoProxy =
				AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
		// 如果@EnableAspectJAutoProxy注解上proxyTargetClass和exposeProxy属性的值是true,
        // 就给AnnotationAwareAspectJAutoProxyCreator的beanDifinition设上proxyTargetClass
        // 和exposeProxy的属性值为true
        if (enableAspectJAutoProxy != null) {
			if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
				AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
			}
			if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
				AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
			}
		}
	}

}
@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
    return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
}

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

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

@Nullable
private static BeanDefinition registerOrEscalateApcAsRequired(
    Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {

    Assert.notNull(registry, "BeanDefinitionRegistry must not be null");

    // 如果已经存在一个自动代理创建器(自定义),如果类型不一样,则比较优先级,
    // 那个优先级高,即使用哪个类型,类型一样就使用自定义的
    if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
        BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
        if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
            int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
            int requiredPriority = findPriorityForClass(cls);
            if (currentPriority < requiredPriority) {
                apcDefinition.setBeanClassName(cls.getName());
            }
        }
        return null;
    }

    // 没有自定义的,就使用spring的
    RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
    beanDefinition.setSource(source);
    beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
    beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
    registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
    return beanDefinition;
}

由于AnnotationAwareAspectJAutoProxyCreator实现了BeanPostProcessor接口,所以在registerBeanPostProcessors(beanFactory)方法中会将它注册成bean后置处理器,用于生成代理。

AnnotationAwareAspectJAutoProxyCreator

在doCreateBean之前,会先执行resolveBeforeInstantiation方法,该方法中会调用AbstractAutoProxyCreator中的postProcessBeforeInstantiation方法,其主要目的在于如果用户使用了自定义的TargetSource对象,则直接使用该对象生成目标对象,而不会使用Spring的默认逻辑生成目标对象,并且这里会判断各个切面逻辑是否可以应用到当前bean上,如果可以,则直接应用,也就是说TargetSource为使用者在Aop中提供了一个自定义生成目标bean逻辑的方式,并且会应用相应的切面逻辑
Spring AOP 源码解析_第1张图片

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

    if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
        if (this.advisedBeans.containsKey(cacheKey)) {
            return null;
        }
        // 判断给定的bean类是否是不应代理的基础结构类。
        // 默认实现将Advices,Advisor和AopInfrastructureBeans视为基础结构类
        // 这里的shouldSkip方法会解析所有advisor并缓存起来,所以后面的步骤无需再解析advisor
        if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return null;
        }
    }

    // Create proxy here if we have a custom TargetSource.
    // Suppresses unnecessary default instantiation of the target bean:
    // The TargetSource will handle target instances in a custom fashion.
    // 到这里说明该bean可以被代理,所以去获取自定义目标类,如果没有定义,则跳过,
    // 如果有自定义的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方法会解析所有advisor并缓存起来,所以后面的步骤无需再解析advisor。这里的解析逻辑放到下面再讲。

正常情况下,生成代理是在初始化bean操作中

// 处理 bean 初始化完成后的各种回调,比如后置处理,init方法等,以及AOP加强也在这里完成,返回的是代理对象
exposedObject = initializeBean(beanName, exposedObject, mbd);

initializeBean中在初始化完后会调用后置处理器的postProcessAfterInitialization方法

// 调用BeanPostProcessor的postProcessAfterInitialization方法,比如AOP增强
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
        throws BeansException {
    Object result = existingBean;
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        // AbstractAutoProxyCreator aop增强逻辑
        Object current = processor.postProcessAfterInitialization(result, beanName);
        if (current == null) {
            return result;
        }
        result = current;
    }
    return result;
}

从processor.postProcessAfterInitialization正式准备开始aop增强

AbstractAutoProxyCreator

@Override
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;
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
    if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
        return bean;
    }
    // 从缓存中获知该bean不需要生成代理
    if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
        return bean;
    }
    // 如果是基础设施类(Pointcut、Advice、Advisor 等接口的实现类),或是应该跳过的类,
    // 则不应该生成代理,此时直接返回 bean
    if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }

    // 获取可应用于该bean的advisor增强器
    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;
    }
    // 不用代理,直接返回bean
    this.advisedBeans.put(cacheKey, Boolean.FALSE);
    return bean;
}

判断是否需要生成代理

如果是基础设施类(是 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;
}

这里的AopInfrastructureBean接口是代表免被aop代理的标记接口。如果bean实现了该接口,表明它是一个aop的基础类,那么这个类是不会被代理的,即便它有匹配的advisor。
或是应该跳过的类(指的是已经判断过的,一般是多例的情况下),则会直接返回原始的bean。在shouldSkip方法中,会先将所有的Advisor缓存起来,后面就无需再解析。

@Override
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
    // 获取到所有候选advisor
    List<Advisor> candidateAdvisors = findCandidateAdvisors();
    // 遍历每个advisor,如果advisor是AspectJPointcutAdvisor的实现类并且当前beanName跟
    // advisor的切面名称相同,就表示要跳过该类,不进行代理
    for (Advisor advisor : candidateAdvisors) {
        if (advisor instanceof AspectJPointcutAdvisor &&
            ((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
            return true;
        }
    }
    return super.shouldSkip(beanClass, beanName);
}

获取所有的advisor

@Override
protected List<Advisor> findCandidateAdvisors() {
    // 调用父类方法,获取xml配置的aop,即获取Advisor类型的bean
    List<Advisor> advisors = super.findCandidateAdvisors();
    // Build Advisors for all AspectJ aspects in the bean factory.
    // 查找标注@Aspect的bean ,并解析bean的标注 @Before, @After, @AfterReturning, @AfterThrowing 的方法,即查找增强器。并加入缓存中
    if (this.aspectJAdvisorsBuilder != null) {
        advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
    }
    return advisors;
}

会调用父类的findCandidateAdvisors方法,毕竟在用注解的同时xml配置也是生效的,之后再解析@Aspect注解的bean,将里面的增强方法提取出来,结果与上面的方法合并,即最终的全部Advisor列表。

构建advisor

来看下解析@Aspect的方法:
BeanFactoryAspectJAdvisorsBuilder

/**
 * 在当前的bean工厂中查找带有AspectJ注释的aspect bean,然后返回它们的Spring AOP Advisor列表。
 * 为每个AspectJ通知方法创建一个Spring Advisor
 * 只有第一次执行时会扫描全部的bean,后续只需访问缓存即可
 *
 * 获取注解信息
 *   1. 获取所有的BeanName , 从beanFactor中进行提取
 *   2. 遍历所有的beanName ,并找出声明AspectJ注解的类,进行进一步的处理
 *   3. 对标记AspectJ注解的类进行增强的提起操作
 *   4. 将提取的结果加入到缓存中
 */
public List<Advisor> buildAspectJAdvisors() {
    List<String> aspectNames = this.aspectBeanNames;
	// 1、如果aspectBeanNames不为空,说明已经解析过了,无需再解析
    if (aspectNames == null) {
        synchronized (this) {
            aspectNames = this.aspectBeanNames;
            if (aspectNames == null) {
                List<Advisor> advisors = new ArrayList<>();
                aspectNames = new ArrayList<>();
                // 获取给定类型的所有bean名称,这里是Object类型,相当于获取全部
                String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                        this.beanFactory, Object.class, true, false);
                // 2、
                for (String beanName : beanNames) {
                    if (!isEligibleBean(beanName)) {
                        continue;
                    }
                    // We must be careful not to instantiate beans eagerly as in this case they
                    // would be cached by the Spring container but would not have been weaved.
                    Class<?> beanType = this.beanFactory.getType(beanName);
                    if (beanType == null) {
                        continue;
                    }
                    // 判断类上是否有@Aspect注解,没有就跳过
                    if (this.advisorFactory.isAspect(beanType)) {
                        // 该bean是个切面类,将切面类名称缓存到aspectNames
                        aspectNames.add(beanName);
                        AspectMetadata amd = new AspectMetadata(beanType, beanName);
                        if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
                            MetadataAwareAspectInstanceFactory factory =
                                    new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
                            // 获取类中的advisor(即Before、After等)
                            List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
                            if (this.beanFactory.isSingleton(beanName)) {
                                // 如果该bean是单例,就放到advisorsCache缓存中
                                this.advisorsCache.put(beanName, classAdvisors);
                            }
                            else {
                                // 否则将解析和创建advisor的工厂缓存起来,
                                // 多例不会缓存advisor,每次调到都是重新创建
                                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));
                        }
                    }
                }
                // 3
                this.aspectBeanNames = aspectNames;
                return advisors;
            }
        }
    }

    if (aspectNames.isEmpty()) {
        return Collections.emptyList();
    }
    List<Advisor> advisors = new ArrayList<>();
    // 4
    for (String aspectName : aspectNames) {
        // 如果aspectName对应的切面类是多例,则这里获取到的缓存是空,
        // 会每次通过aspectFactoryCache缓存中的工厂类重新解析和创建advisor
        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;
}

1、先获取aspectBeanNames缓存,判断是否存在,若存在,说明之前已经解析过被@Aspect注解标记过的类了,无需再次耗时解析,跳到第4步,否则下一步;
2、获取全部Object类型的bean名称,循环遍历判断类上是否有@Aspect注解,若有,将bean name添加到aspectNames中,执行this.advisorFactory.getAdvisors(factory)方法解析出Advisor列表,放到advisorsCache缓存中,没有则接着遍历;
3、将上述中aspectNames赋值给缓存aspectBeanNames,表示已经解析过了,后面再来直接取缓存就可以了,最后返回advisor列表;
4、如果第一步发现@Aspect类解析过了,则跳到这一步,遍历aspectNames列表,根据bean name从advisorsCache缓存中逐一取出advisor列表合并成一个列表后返回。

接下来来看如何解析被@Aspect注解标记的类

ReflectiveAspectJAdvisorFactory
一些代码也看不懂,咱就抓主干脉络

@Override
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
    Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
    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
        Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), 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;
}

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);
    methods.sort(METHOD_COMPARATOR);
    return methods;
}

主要来看看getAdvisor方法

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

    validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
    // 获取切点实现类(主要封装了表达式)
    AspectJExpressionPointcut expressionPointcut = getPointcut(
        candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
    // 空则表示是普通方法,不是切点
    if (expressionPointcut == null) {
        return null;
    }
    // 构建一个advisor
    return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
                                                          this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}

上述方法主要有两个步骤,获取表达式切点和生成advisor,如果获取到的切点为空,则表示该方法不是一个增强方法,只是普通方法。
先来看如何获取表达式切点:

@Nullable
private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
    // 获取方法上的 AspectJ 相关注解,包括 Pointcut.class, Around.class, Before.class, After.class,
    // AfterReturning.class, AfterThrowing.class
    AspectJAnnotation<?> aspectJAnnotation =
        AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
    if (aspectJAnnotation == null) {
        return null;
    }
    // 创建一个 AspectJExpressionPointcut 对象
    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;
}

再看如何创建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;

    // 懒加载
    if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
        // Static part of the pointcut is a lazy type.
        Pointcut preInstantiationPointcut = Pointcuts.union(
                aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);

        // Make it dynamic: must mutate from pre-instantiation to post-instantiation state.
        // If it's not a dynamic pointcut, it may be optimized out
        // by the Spring AOP infrastructure after the first evaluation.
        this.pointcut = new PerTargetInstantiationModelPointcut(
                this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory);
        this.lazy = true;
    }
    else {
        // 单例aspect.
        this.pointcut = this.declaredPointcut;
        this.lazy = false;
        this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
    }
}

正常情况下是进入到else逻辑中,由于advisor是包含切点和通知的,所以还需要对advice进行实例化。

private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) {
    Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut,
                                                         this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
    return (advice != null ? advice : EMPTY_ADVICE);
}
@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()) {
        // 如果是切面即@Pointcut则返回null
        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);
    }

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

    return springAdvice;
}

上面一些代码看不懂,就不再分析了。按这样循环每个bean的每个方法就将所有被@Aspect注解标记的类中的方法解析成Advisor列表了并存放在缓存中了。
上面那么一大段都是解析shouldSkip方法,下面重新放出该段源码

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
    if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
        return bean;
    }
    // 从缓存中获知该bean不需要生成代理
    if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
        return bean;
    }
    // 如果是基础设施类(Pointcut、Advice、Advisor 等接口的实现类),或是应该跳过的类,
    // 则不应该生成代理,此时直接返回 bean
    if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }

    // 获取可应用于该bean的advisor增强器
    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;
    }
    // 不用代理,直接返回bean
    this.advisedBeans.put(cacheKey, Boolean.FALSE);
    return bean;
}

当判断通过表示该bean需要动态代理增强后,就要获取可应用于该bean的advisor增强器

筛选出匹配的advisor

@Override
@Nullable
protected Object[] getAdvicesAndAdvisorsForBean(
    Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
	// 获取可应用于该bean的advisor增强器
    List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
    // 空表示没有匹配的增强,无需生成代理
    if (advisors.isEmpty()) {
        return DO_NOT_PROXY;
    }
    return advisors.toArray();
}
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
    // 获取全部advisor
    List<Advisor> candidateAdvisors = findCandidateAdvisors();
    // 筛选出匹配该bean的advisor,通过 ClassFilter 和 MethodMatcher对目标类和方法进行匹配
    List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
    // 对eligibleAdvisors进行了扩展,添加了ExposeInvocationInterceptor拦截器,
    // 用来传递MethodInvocation的
    extendAdvisors(eligibleAdvisors);
    if (!eligibleAdvisors.isEmpty()) {
        // 排序
        eligibleAdvisors = sortAdvisors(eligibleAdvisors);
    }
    return eligibleAdvisors;
}

先获取全部的advisor,获取全部advisor由于在前面已经解析过了并且将所有的advisor都缓存了,所以这里会直接从缓存中获取到。
之后再从中筛选出匹配的advisor。

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

    ProxyCreationContext.setCurrentProxiedBeanName(beanName);
    try {
        // 使用aop工具类类筛选
        return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
    }
    finally {
        ProxyCreationContext.setCurrentProxiedBeanName(null);
    }
}

AopUtils

public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
    if (candidateAdvisors.isEmpty()) {
        return candidateAdvisors;
    }
    // 用来保存筛选出来的advisor
    List<Advisor> eligibleAdvisors = new ArrayList<>();
    // 我们一般很少用IntroductionAdvisor,处理引介增强的
    for (Advisor candidate : candidateAdvisors) {
        if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
            eligibleAdvisors.add(candidate);
        }
    }
    boolean hasIntroductions = !eligibleAdvisors.isEmpty();
    // 遍历每个advisor
    for (Advisor candidate : candidateAdvisors) {
        if (candidate instanceof IntroductionAdvisor) {
            // 因为上面已经处理过了,所以这里跳过
            continue;
        }
        // 重点是这里,如果匹配上,就加入到eligibleAdvisors,最后返回
        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");
    // 在类层面进行粗筛
    // 这里会调用aspectj的代码进行验证是否匹配
    if (!pc.getClassFilter().matches(targetClass)) {
        return false;
    }

    // 对每个方法进行匹配,只要有一个匹配,就返回true,
    // 也是调用aspectj的代码进行验证是否匹配
    MethodMatcher methodMatcher = pc.getMethodMatcher();
    if (methodMatcher == MethodMatcher.TRUE) {
        // 任何方法都匹配
        return true;
    }

    // IntroductionAwareMethodMatcher是MethodMatcher的一种特殊类型,
    // AspectJExpressionPointcut实现了该接口
    IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
    if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
        introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
    }

    Set<Class<?>> classes = new LinkedHashSet<>();
    if (!Proxy.isProxyClass(targetClass)) {
        // 向classes添加目标类Class
        classes.add(ClassUtils.getUserClass(targetClass));
    }
    // 添加实现的接口
    classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));

    for (Class<?> clazz : classes) {
        Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
        // 遍历每个方法,调用方法匹配器的matches方法校验是否与表达式匹配
        for (Method method : methods) {
            if (introductionAwareMethodMatcher != null ?
                introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
                methodMatcher.matches(method, targetClass)) {
                return true;
            }
        }
    }

    return false;
}

最后就是根据匹配到的advisor创建代理对象

创建代理

protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
		@Nullable Object[] specificInterceptors, TargetSource targetSource) {

    if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
        AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
    }

    // 创建一个代理工厂
    ProxyFactory proxyFactory = new ProxyFactory();
    // 复制配置
    proxyFactory.copyFrom(this);

    if (!proxyFactory.isProxyTargetClass()) {
        if (shouldProxyTargetClass(beanClass, beanName)) {
            proxyFactory.setProxyTargetClass(true);
        }
        else {
            evaluateProxyInterfaces(beanClass, proxyFactory);
        }
    }

    // 将specificInterceptors里的对象封装为advisor
    Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
    // 将advisors设置到proxyFactory
    proxyFactory.addAdvisors(advisors);
    proxyFactory.setTargetSource(targetSource);
    customizeProxyFactory(proxyFactory);

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

    // 创建代理
    return proxyFactory.getProxy(getProxyClassLoader());
}

使用代理工厂创建代理

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

先创建一个aop代理创建器,这个方法的主要功能是,根据optimize、ProxyTargetClass等参数来决定生成Jdk动态代理,还是生成Cglib代理,通过代理创建器来创建代理

protected final synchronized AopProxy createAopProxy() {
    if (!this.active) {
        activate();
    }
    return getAopProxyFactory().createAopProxy(this);
}

获取工厂来创建,aopProxyFactory默认就是DefaultAopProxyFactory
创建aop代理创建器

public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
    if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
        Class<?> targetClass = config.getTargetClass();
        if (targetClass == null) {
            throw new AopConfigException("TargetSource cannot determine target class: " +
                                         "Either an interface or a target is required for proxy creation.");
        }
        if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
            // jdk动态代理
            return new JdkDynamicAopProxy(config);
        }
        // cglib代理
        return new ObjenesisCglibAopProxy(config);
    }
    else {
        // jdk动态代理
        return new JdkDynamicAopProxy(config);
    }
}

这里会根据目标类是否实现接口以及配置信息还有目标类类型来判断是使用jdk动态代理还是cglib动态代理。这里就解析jdk动态代理,所以这里返回JdkDynamicAopProxy,然后通过JdkDynamicAopProxy来创建代理。

@Override
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);
    return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}

通过Proxy.newProxyInstance方法最终创建代理对象,由于JdkDynamicAopProxy实现了InvocationHandler接口,所以这里newProxyInstance方法的第三个参数直接传this了。JdkDynamicAopProxy中有一个属性private final AdvisedSupport advised,该属性里包含跟目标类匹配的所有advisor。

这里的JdkDynamicAopProxy类似下面这个类

public class CustomInvocationHandler implements InvocationHandler {

	private Object target;

	public CustomInvocationHandler(Object target) {
		this.target = target;
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		System.out.println("前置增强");
		Object result = method.invoke(target, args);
		System.out.println("后置增强");
		return result;
	}

	public Object getProxy() {
		return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),
				this);
	}
}

到这里就创建出了代理对象来,当调用方法时,会调用到InvocationHandler接口的invoke方法,来进行增强处理,这里就是JdkDynamicAopProxy的invoke方法

调用方法执行增强逻辑

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

    TargetSource targetSource = this.advised.targetSource;
    Object target = null;

    try {
        // 如果调用的是equals或hashCode方法,就不进行增强处理
        if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
            // 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;

        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 = targetSource.getTarget();
        Class<?> targetClass = (target != null ? target.getClass() : null);

        // 获取到可以应用于调用方法的拦截器(将Advice封装为MethodInterceptor)
        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.
            // 没有advisor可以应用与该方法,则直接反射调用原方法
            Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
            retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
        }
        else {
            // 创建一个MethodInvocation用来调用每个拦截器
            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) {
    // 根据method生成一个key
    MethodCacheKey cacheKey = new MethodCacheKey(method);
    // 从缓存中获取该方法的拦截器
    List<Object> cached = this.methodCache.get(cacheKey);
    if (cached == null) {
        // key对应的缓存为空就需要筛选出来后设置到缓存中
        cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
            this, method, targetClass);
        this.methodCache.put(cacheKey, cached);
    }
    return cached;
}

该方法用来筛选可以应用于该方法的advisor,因为不是每个方法都需要增强

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();
    // 获取该bean上的advisor列表
    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;
            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加入到拦截器列表中
                    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;
}

看下如何将Advice转换为MethodInterceptor

Advice转换为MethodInterceptor

public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
    List<MethodInterceptor> interceptors = new ArrayList<>(3);
    // 取出advisor中的advice
    Advice advice = advisor.getAdvice();
    // 本身就是MethodInterceptor实现类,就直接加入到interceptors,
    // AspectJAroundAdvice、AspectJAfterAdvice、AspectJAfterThrowingAdvice
    // 这几个增强器都实现了 MethodInterceptor 接口
    if (advice instanceof MethodInterceptor) {
        interceptors.add((MethodInterceptor) advice);
    }
    // 其它的就根据适配器转换,AspectJMethodBeforeAdvice和AspectJAfterReturningAdvice
    for (AdvisorAdapter adapter : this.adapters) {
        if (adapter.supportsAdvice(advice)) {
            interceptors.add(adapter.getInterceptor(advisor));
        }
    }
    if (interceptors.isEmpty()) {
        throw new UnknownAdviceTypeException(advisor.getAdvice());
    }
    return interceptors.toArray(new MethodInterceptor[0]);
}

默认有以下3种适配器
Spring AOP 源码解析_第2张图片

分别用来转换MethodBeforeAdvice,AfterReturningAdvice和ThrowsAdvice。

class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable {

	@Override
	public boolean supportsAdvice(Advice advice) {
		return (advice instanceof MethodBeforeAdvice);
	}

	@Override
	public MethodInterceptor getInterceptor(Advisor advisor) {
		MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice();
		return new MethodBeforeAdviceInterceptor(advice);
	}

}

直接将MethodBeforeAdvice封装进MethodBeforeAdviceInterceptor,AfterReturningAdviceAdapter和ThrowsAdviceAdapter也是一样的做法。

至此我们获取到了一个拦截器列表,列表中可能包括AspectJAroundAdvice、AspectJAfterAdvice、AspectJAfterThrowingAdvice、MethodBeforeAdviceInterceptor、AfterReturningAdviceInterceptor。
接下来 ReflectiveMethodInvocation 类进行了链的封装,而在ReflectiveMethodInvocation类的proceed方法中实现了拦截器的逐一调用。

执行拦截器链

@Override
@Nullable
public Object proceed() throws Throwable {
    // currentInterceptorIndex从-1开始,并且使用前会先+1,
    // interceptorsAndDynamicMethodMatchers 就是拦截器链中的拦截器个数,
    // currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1 说明
    // 拦截器链执行完了,就接着执行被代理方法
    if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
        return invokeJoinpoint();
    }

    // 取出下标为currentInterceptorIndex的拦截器执行
    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 {
        // 调用拦截器,将当前对象ReflectiveMethodInvocation传进去
        return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
    }
}

将每个通知都设置上后的拦截器顺序如下

@Component
@Aspect
public class AopAspect {

 
    @Pointcut("execution(* com.huang.sourcelearn.Student.*(..))")
    public void pointcut() {
    }

    @After("pointcut()")
    public void after() {
        System.out.println("after");
    }

	@AfterThrowing("pointcut()")
	public void afterThrowing() {
		System.out.println("afterThrowing");
	}

	@Before("pointcut()")
	public void before() {
		System.out.println("before");
	}

	@AfterReturning("pointcut()")
	public void afterReturning() {
		System.out.println("afterReturning");
	}
 
    @Around("pointcut()")
    public Object around(ProceedingJoinPoint proceedingJoinPoint) throws InterruptedException {
        System.out.println("around advice start");
        try {
            Object result = proceedingJoinPoint.proceed();
            System.out.println("result: " + result);
            System.out.println("around advice end");
            return result;
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            return null;
        }
    }
}

Spring AOP 源码解析_第3张图片

所以先来看下ExposeInvocationInterceptor的invoke方法

ExposeInvocationInterceptor

@Override
public Object invoke(MethodInvocation mi) throws Throwable {
    MethodInvocation oldInvocation = invocation.get();
    invocation.set(mi);
    try {
        return mi.proceed();
    }
    finally {
        invocation.set(oldInvocation);
    }
}

其中invocation是一个ThreadLocal

private static final ThreadLocal<MethodInvocation> invocation =
			new NamedThreadLocal<>("Current AOP method invocation");

这里将传进来的MethodInvocation设置到ThreadLocal中,这个拦截器就干了这一件事,然后就通过mi.proceed()方法返回ReflectiveMethodInvocation类调下一个拦截器,下一个是AspectJAfterThrowingAdvice

AspectJAfterThrowingAdvice

public class AspectJAfterThrowingAdvice extends AbstractAspectJAdvice
		implements MethodInterceptor, AfterAdvice, Serializable {

	public AspectJAfterThrowingAdvice(
			Method aspectJBeforeAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {

		super(aspectJBeforeAdviceMethod, pointcut, aif);
	}

	@Override
	public boolean isBeforeAdvice() {
		return false;
	}

	@Override
	public boolean isAfterAdvice() {
		return true;
	}

	@Override
	public void setThrowingName(String name) {
		setThrowingNameNoCheck(name);
	}

	@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		try {
            // 直接调用了ReflectiveMethodInvocation的proceed()方法
			return mi.proceed();
		}
		catch (Throwable ex) {
			if (shouldInvokeOnThrowing(ex)) {
				invokeAdviceMethod(getJoinPointMatch(), null, ex);
			}
			throw ex;
		}
	}

	private boolean shouldInvokeOnThrowing(Throwable ex) {
		return getDiscoveredThrowingType().isAssignableFrom(ex.getClass());
	}

}

由于@AfterThrowing是在有抛异常时才执行,所以会直接重新调用了ReflectiveMethodInvocation的proceed()方法,去执行下一个拦截器,然后在catch中捕获异常,执行增强逻辑,最后重新抛出异常。
通过调用父类AbstractAspectJAdvice的invokeAdviceMethod方法来执行通知方法,下面几个也是如此

protected Object invokeAdviceMethod(
    	@Nullable JoinPointMatch jpMatch, @Nullable Object returnValue, @Nullable Throwable ex)
    throws Throwable {
	// argBinding用来绑定通知方法的参数
    return invokeAdviceMethodWithGivenArgs(argBinding(getJoinPoint(), jpMatch, returnValue, ex));
}

protected Object invokeAdviceMethodWithGivenArgs(Object[] args) throws Throwable {
    Object[] actualArgs = args;
    // 通知方法没有参数则不需传参
    if (this.aspectJAdviceMethod.getParameterCount() == 0) {
        actualArgs = null;
    }
    try {
        ReflectionUtils.makeAccessible(this.aspectJAdviceMethod);
        // aspectJAdviceMethod是通知方法,通过反射调用到通知方法
        return this.aspectJAdviceMethod.invoke(this.aspectInstanceFactory.getAspectInstance(), actualArgs);
    }
    catch (IllegalArgumentException ex) {
        throw new AopInvocationException("Mismatch on arguments to advice method [" +
                                         this.aspectJAdviceMethod + "]; pointcut expression [" +
                                         this.pointcut.getPointcutExpression() + "]", ex);
    }
    catch (InvocationTargetException ex) {
        throw ex.getTargetException();
    }
}

AfterReturningAdviceInterceptor

public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable {

	private final AfterReturningAdvice advice;


	/**
	 * Create a new AfterReturningAdviceInterceptor for the given advice.
	 * @param advice the AfterReturningAdvice to wrap
	 */
	public AfterReturningAdviceInterceptor(AfterReturningAdvice advice) {
		Assert.notNull(advice, "Advice must not be null");
		this.advice = advice;
	}


	@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		Object retVal = mi.proceed();
        // 反射调用通知方法
		this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
		return retVal;
	}

}

@AfterReturning是在方法正常返回时执行,所以也是先继续执行,执行完代理的方法获取到返回值后执行通知方法。
通过调用内部的AfterReturningAdvice对象的afterReturning方法来执行通知方法

public void afterReturning(@Nullable Object returnValue, Method method, Object[] args, @Nullable Object target) throws Throwable {
    if (shouldInvokeOnReturnValueOf(method, returnValue)) {
        // 反射调用通知方法
        invokeAdviceMethod(getJoinPointMatch(), returnValue, null);
    }
}

这里的invokeAdviceMethod方法照样也是调用父类的方法,上面已经解析过了。
然后是AspectJAfterAdvice。

AspectJAfterAdvice

public class AspectJAfterAdvice extends AbstractAspectJAdvice
		implements MethodInterceptor, AfterAdvice, Serializable {

	public AspectJAfterAdvice(
			Method aspectJBeforeAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {

		super(aspectJBeforeAdviceMethod, pointcut, aif);
	}


	@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		try {
			return mi.proceed();
		}
		finally {
        	// 在finally块中,所以是无论如何都会执行的
			invokeAdviceMethod(getJoinPointMatch(), null, null);
		}
	}

	@Override
	public boolean isBeforeAdvice() {
		return false;
	}

	@Override
	public boolean isAfterAdvice() {
		return true;
	}

}

AspectJAroundAdvice

public class AspectJAroundAdvice extends AbstractAspectJAdvice implements MethodInterceptor, Serializable {

	public AspectJAroundAdvice(
			Method aspectJAroundAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {

		super(aspectJAroundAdviceMethod, pointcut, aif);
	}


	@Override
	public boolean isBeforeAdvice() {
		return false;
	}

	@Override
	public boolean isAfterAdvice() {
		return false;
	}

	@Override
	protected boolean supportsProceedingJoinPoint() {
		return true;
	}

	@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		if (!(mi instanceof ProxyMethodInvocation)) {
			throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
		}
		ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi;
        // 构建一个ProceedingJoinPoint,将MethodInvocation封装到ProceedingJoinPoint中
		ProceedingJoinPoint pjp = lazyGetProceedingJoinPoint(pmi);
		JoinPointMatch jpm = getJoinPointMatch(pmi);
        // 反射调用通知方法
		return invokeAdviceMethod(pjp, jpm, null, null);
	}

	/**
	 * Return the ProceedingJoinPoint for the current invocation,
	 * instantiating it lazily if it hasn't been bound to the thread already.
	 * @param rmi the current Spring AOP ReflectiveMethodInvocation,
	 * which we'll use for attribute binding
	 * @return the ProceedingJoinPoint to make available to advice methods
	 */
	protected ProceedingJoinPoint lazyGetProceedingJoinPoint(ProxyMethodInvocation rmi) {
		return new MethodInvocationProceedingJoinPoint(rmi);
	}

}

AspectJAroundAdvice中的invoke方法跟其它拦截器有些区别,最大区别就是没有调用mi的proceed方法,因为在自定义的环绕通知方法中,由我们自己调用proceed方法。
Spring AOP 源码解析_第4张图片

MethodBeforeAdviceInterceptor

public class MethodBeforeAdviceInterceptor implements MethodInterceptor, BeforeAdvice, Serializable {

    // AspectJMethodBeforeAdvice
	private final MethodBeforeAdvice advice;


	/**
	 * Create a new MethodBeforeAdviceInterceptor for the given advice.
	 * @param advice the MethodBeforeAdvice to wrap
	 */
	public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
		Assert.notNull(advice, "Advice must not be null");
		this.advice = advice;
	}


	@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
        // 通过反射调用通知方法
		this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
		return mi.proceed();
	}

}

@Before会先执行通知方法,完成前置增强,之后调用mi.proceed()重新回到ReflectiveMethodInvocation,由于Before的拦截器是最后执行的,所以这里所有的拦截器都执行到了,接着就是反射调用目标方法

@Override
@Nullable
public Object proceed() throws Throwable {
    //	We start with an index of -1 and increment early.
    if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
        // 当所有的拦截器都执行到后,反射调用目标方法
        return invokeJoinpoint();
    }

    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 {
        // 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);
    }
}

@Nullable
protected Object invokeJoinpoint() throws Throwable {
    return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments);
}
@Nullable
public static Object invokeJoinpointUsingReflection(@Nullable Object target, Method method, Object[] args)
    throws Throwable {

    // Use reflection to invoke the method.
    try {
        ReflectionUtils.makeAccessible(method);
        // 反射调用方法
        return method.invoke(target, args);
    }
    catch (InvocationTargetException ex) {
        // Invoked method threw a checked exception.
        // We must rethrow it. The client won't see the interceptor.
        throw ex.getTargetException();
    }
    catch (IllegalArgumentException ex) {
        throw new AopInvocationException("AOP configuration seems to be invalid: tried calling method [" +
                                         method + "] on target [" + target + "]", ex);
    }
    catch (IllegalAccessException ex) {
        throw new AopInvocationException("Could not access method [" + method + "]", ex);
    }
}

由于调用拦截器采用了责任链模式,所以当执行完目标方法后,会一个个的反向退回去,执行后置处理。

这个代理类调用过程,我们可以看到是一个递归的调用过程,通过ReflectiveMethodInvocation类中Proceed方法递归调用,顺序执行拦截器链中AspectJAfterThrowingAdvice、AfterReturningAdviceInterceptor、AspectJAfterAdvice、AspectJAroundAdvice、MethodBeforeAdviceInterceptor这几个拦截器,在拦截器中反射调用增强方法。

你可能感兴趣的:(源码学习,#,Spring,Spring,AOP)