Source code analysis of Spring AOP annotation method

Source code analysis of Spring AOP annotation method

TSMYK Java technology programming

Preface

In the last article Detailed Explanation of the Use of Spring AOP Function, I learned a detailed usage of Sprig AOP. Now let's see how it is implemented in Spring.

aspectj-autoproxy

We know that if you want to use Spring AOP, you must first add the configuration item <aop:aspectj-autoproxy expose-proxy="true" proxy-target-class="true"/> in the configuration file, and the two attributes are Optional. For each tag in Spring, there is a corresponding parser for parsing, and for aspectj-autoproxy tags, the AspectJAutoProxyBeanDefinitionParser parser is used for parsing, as shown below:


public class AopNamespaceHandler extends NamespaceHandlerSupport {
    @Override
    public void init() {
        registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
        // 注册 aspectj-autoproxy 标签的解析器
        registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
        registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());
        registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
    }
}

There are two main functions in AspectJAutoProxyBeanDefinitionParser. One is to register the AnnotationAwareAspectJAutoProxyCreator bean, and the other is to parse the two attributes of <aop:aspectj-autoproxy />. The AOP function is basically done by AnnotationAwareAspectJAutoProxyCreator;

Register AnnotationAwareAspectJAutoProxyCreator

All parsers implement the interface BeanDefinitionParser, and the entry is parsed from the parse method, and the parse method of AspectJAutoProxyBeanDefinitionParser is as follows:


class AspectJAutoProxyBeanDefinitionParser implements BeanDefinitionParser {
    public BeanDefinition parse(Element element, ParserContext parserContext) {
        // 注册AnnotationAwareAspectJAutoProxyCreator bean 和处理标签的两个属性
        AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
        // 处理子标签
        extendBeanDefinition(element, parserContext);
        return null;
    }
}

The AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary method is as follows:


public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(ParserContext parserContext, Element sourceElement) {
    // 注册 AnnotationAwareAspectJAutoProxyCreator
    BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(
            parserContext.getRegistry(), parserContext.extractSource(sourceElement));
    // 解析标签的两个属性expose-proxy 和 proxy-target-class
    useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
    // 注册组件并通知,便于监听器进一步处理,这里可以不用看
    registerComponentIfNecessary(beanDefinition, parserContext);
}

In this method, three functions are mainly completed, and each line of code completes one function:

  1. Register AnnotationAwareAspectJAutoProxyCreator
  2. Processing expose-proxy and proxy-target-class attributes
  3. Register components and notify

    Register AnnotationAwareAspectJAutoProxyCreator


public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
    return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
// 注册
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) {
    //如果已经注册且与现在的不一致,则需要根据优先级来判断到底需要使用哪一个
    //AUTO_PROXY_CREATOR_BEAN_NAME=org.springframework.aop.config.internalAutoProxyCreator
    if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
        BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
        // 如果缓存中和现在注册的class不一样
        if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
            int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
            int requiredPriority = findPriorityForClass(cls);
            // 判断优先级,如果现在的优先级比缓存中的大,则取现在的这个
            if (currentPriority < requiredPriority) {
                apcDefinition.setBeanClassName(cls.getName());
            }
        }
        //如果相同,则无需再创建
        return null;
    }
    // 如果还没有注册,则进行注册
    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;
}

Processing expose-proxy and proxy-target-class attributes


处理 expose-proxy 和 proxy-target-class 属性

private static void useClassProxyingIfNecessary(BeanDefinitionRegistry registry,Element sourceElement) {
    if (sourceElement != null) {
        // 获取proxy-target-class的值
        boolean proxyTargetClass = Boolean.parseBoolean(sourceElement.getAttribute(PROXY_TARGET_CLASS_ATTRIBUTE));
        if (proxyTargetClass) {
            AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
        }
        // 获取 expose-proxy的值
        boolean exposeProxy = Boolean.parseBoolean(sourceElement.getAttribute(EXPOSE_PROXY_ATTRIBUTE));
        if (exposeProxy) {
            AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
        }
    }
}
//设置属性 proxyTargetClass 为true
public static void forceAutoProxyCreatorToUseClassProxying(BeanDefinitionRegistry registry) {
    if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
        BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
        definition.getPropertyValues().add("proxyTargetClass", Boolean.TRUE);
    }
}
//设置属性 exposeProxy为true
public static void forceAutoProxyCreatorToExposeProxy(BeanDefinitionRegistry registry) {
    if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
        BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
        definition.getPropertyValues().add("exposeProxy", Boolean.TRUE);
    }
}

At this point, the registration of AnnotationAwareAspectJAutoProxyCreator is completed. As mentioned above, the functions of AOP are basically completed by AnnotationAwareAspectJAutoProxyCreator. Next, let's take a look at how this class completes AOP operations.

Parse Advce

Let's take a look at the class diagram of AnnotationAwareAspectJAutoProxyCreator as follows:

Source code analysis of Spring AOP annotation method
As can be seen from the above class diagram, AnnotationAwareAspectJAutoProxyCreator implements BeanPostProcessor, and the bean of this interface is implemented in Spring. When Spring loads the bean, it will call its postProcessAfterInitializatio method before initialization; the postProcessAfterInitialization method of the parent class AbstractAutoProxyCreator is implemented as follows:


public Object postProcessAfterInitialization(Object bean, String beanName) {
    if (bean != null) {
        // 根据beanClass 和 beanName 创建缓存的 key
        Object cacheKey = getCacheKey(bean.getClass(), beanName);
        if (!this.earlyProxyReferences.contains(cacheKey)) {
            // 如果该bean适合被代理,则必须包装
            return wrapIfNecessary(bean, beanName, cacheKey);
        }
    }
    return bean;
}
// 包装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;
    }
    //如果bean是Advice.class, Pointcut.class, Advisor.class, AopInfrastructureBean.class, 则直接返回
    if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
        // 添加该bean不需要增强的标志到缓存中
        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }

    // 获取bean所有的增强
    Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
    if (specificInterceptors != DO_NOT_PROXY) {
        this.advisedBeans.put(cacheKey, Boolean.TRUE);
        // 如果获取到增强,则需要对增强创建代理
        Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
        this.proxyTypes.put(cacheKey, proxy.getClass());
        return proxy;
    }
    // 不需要增强,直接返回
    this.advisedBeans.put(cacheKey, Boolean.FALSE);
    return bean;
}

As can be seen from the above code, before instantiating AnnotationAwareAspectJAutoProxyCreator, the AOP enhancement will be analyzed. After the analysis is enhanced, the enhanced proxy will be created; this article will first look at the enhanced acquisition, and the creation of the proxy will be done in the next article explain.

Get enhanced

Get all its enhancements according to the bean's corresponding class and beanName, for the method getAdvicesAndAdvisorsForBean()


protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {
    // 找出所有符合条件的增强
    List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
    if (advisors.isEmpty()) {
        return DO_NOT_PROXY;
    }
    return advisors.toArray();
}

findEligibleAdvisors () lig :


protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
    // 获取所有增强
    List<Advisor> candidateAdvisors = findCandidateAdvisors();
    // 获取所有增强中适用于 bean 的增强并应用
    List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
    // 对增强进行扩展和排序
    extendAdvisors(eligibleAdvisors);
    if (!eligibleAdvisors.isEmpty()) {
        eligibleAdvisors = sortAdvisors(eligibleAdvisors);
    }
    return eligibleAdvisors;
}

The method to obtain all the enhancements findCandidateAdvisors() After a lot of complicated logical judgments, the AOP-enhanced acquisition and the analysis of pointcut expressions are all implemented within this method:


protected List<Advisor> findCandidateAdvisors() {
    // 调用父类方法加载配置文件中的AOP声明
    List<Advisor> advisors = super.findCandidateAdvisors();
    // 创建所有AspectJ增强
    if (this.aspectJAdvisorsBuilder != null) {
        advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
    }
    return advisors;
}
//父类 findCandidateAdvisors
protected List<Advisor> findCandidateAdvisors() {
    return this.advisorRetrievalHelper.findAdvisorBeans();
}
// 寻找所有符合增强的bean,this.advisorRetrievalHelper.findAdvisorBeans
public List<Advisor> findAdvisorBeans() {
    String[] advisorNames = this.cachedAdvisorBeanNames;
    if (advisorNames == null) {
        // 寻找Advisor注解的beanName
        advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Advisor.class, true, false);
        this.cachedAdvisorBeanNames = advisorNames;
    }
    List<Advisor> advisors = new ArrayList<>();
    for (String name : advisorNames) {
        // 该bean符合增强
        if (isEligibleBean(name)) {
            if (this.beanFactory.isCurrentlyInCreation(name)) {
                // 该bean正创建,则忽略
            }
            else {
                advisors.add(this.beanFactory.getBean(name, Advisor.class));
            }
        }
    }
    return advisors;
}

Get the annotation enhancement of the bean, corresponding to the method this.aspectJAdvisorsBuilder.buildAspectJAdvisors(), find all AspectJ annotated beans, for each enhancement method, a corresponding Advisor will be created, that is, a method for an Advisor


// 查找所有 AspectJ 注解的bean,对于每一个增强方法,都会创建对应的Advisor,即一个方法对于一个Advisor
public List<Advisor> buildAspectJAdvisors() {
    List<String> aspectNames = this.aspectBeanNames;
    // .... 省略一些null判断
    List<Advisor> advisors = new ArrayList<>();
    aspectNames = new ArrayList<>();
    // 获取所有的 beanName
    String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class, true, false);
    for (String beanName : beanNames) {
        // 如果该 bean不符合条件,则跳过
        if (!isEligibleBean(beanName)) {
            continue;
        }
        Class<?> beanType = this.beanFactory.getType(beanName);
        // 如果该 bean 存在 Aspect 注解
        if (this.advisorFactory.isAspect(beanType)) {
            aspectNames.add(beanName);
            // 根据beanType和beanName创建AspectMetadata ,表示增强的元数据
            AspectMetadata amd = new AspectMetadata(beanType, beanName);
            if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
                MetadataAwareAspectInstanceFactory factory = new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
                // 解析标记了 AspectJ 注解中的增强方法
                List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
                if (this.beanFactory.isSingleton(beanName)) {
                    // 如果该 bean是单例,则直接把解析到增强方法放到缓存中
                    this.advisorsCache.put(beanName, classAdvisors);
                }else {
                    //否则把对于的工厂放到缓存中
                    this.aspectFactoryCache.put(beanName, factory);
                }
                advisors.addAll(classAdvisors);
             }else {
                tadataAwareAspectInstanceFactory factory =new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
                this.aspectFactoryCache.put(beanName, factory);
                advisors.addAll(this.advisorFactory.getAdvisors(factory));
            }
            this.aspectBeanNames = aspectNames;
            return advisors;
            }
        }
    }
    if (aspectNames.isEmpty()) {
        return Collections.emptyList();
    }
    // 记录缓存
    List<Advisor> advisors = new ArrayList<>();
    for (String aspectName : aspectNames) {
        List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
        if (cachedAdvisors != null) {
            advisors.addAll(cachedAdvisors);
        }
        else {
            MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
            advisors.addAll(this.advisorFactory.getAdvisors(factory));
        }
    }
    return advisors;
}

The above method has completed the extraction of the Advisor, and the acquisition of the enhancer is handed over to the advisorFactory.getAdvisors() method, as follows:


public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
    //获取标记为 AspectJ 的类
    Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
    // 获取name
    String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
    //验证aspectClass 
    validate(aspectClass);

    //AOP 可以将增强延迟初始化,这里使用装饰器对工厂将包装
    MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory = new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);

    List<Advisor> advisors = new ArrayList<>();
    // 处理每个增强方法,getAdvisorMethods 返回该增强类的所有增强方法
    for (Method method : getAdvisorMethods(aspectClass)) {
        // 每个方法对应一个 advisor
        Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
        if (advisor != null) {
            advisors.add(advisor);
        }
    }

    // 如果寻找的增强器不为空且配置了增强延迟初始化,那么需要在首位添加同步实例化增强器
    if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
        Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
        advisors.add(0, instantiationAdvisor);
    }

    // 获取 DeclareParents 注解
    for (Field field : aspectClass.getDeclaredFields()) {
        Advisor advisor = getDeclareParentsAdvisor(field);
        if (advisor != null) {
            advisors.add(advisor);
        }
    }
    return advisors;
}

//获取增强类的所有增强方法 getAdvisorMethods 
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);
        }
    });
    methods.sort(METHOD_COMPARATOR);
    return methods;
}

Obtaining ordinary enhancers

The normal enhancer is obtained through the getAdvisor() method, which includes the acquisition of pointcut annotations and the enhancement of annotation information generation, as follows:


public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrderInAspect, String aspectName) {
    // 切点信息的获取,如@After, @Before
    AspectJExpressionPointcut expressionPointcut = getPointcut(candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
    // 根据切点信息,生成不同的增强器
    return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod, this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}

Get cut point information getPonitcut:


private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
    // 获取方法上的注解
    AspectJAnnotation<?> aspectJAnnotation = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
    // 使用 AspectJExpressionPointcut 封装切点信息
    AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class<?>[0]);
    // 设置切点表达式如:execution(* *Service*(..))
    ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
    if (this.beanFactory != null) {
        ajexp.setBeanFactory(this.beanFactory);
    }
    return ajexp;
}

// 获取方法上的注解 findAspectJAnnotationOnMethod
protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {
    // ASPECTJ_ANNOTATION_CLASSES 是一个数组:{Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class}
    for (Class<?> clazz : ASPECTJ_ANNOTATION_CLASSES) {
        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) {
        return new AspectJAnnotation<>(result);
    }
    else {
        return null;
    }
}

After the above method obtains the specific pointcut information, it will generate the corresponding enhancer according to the pointcut information. Each pointcut information such as @After, @Before corresponds to an InstantiationModelAwarePointcutAdvisorImpl object, as follows:


new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod, this, aspectInstanceFactory, declarationOrderInAspect, aspectName)

In the process of instantiating the object, there are some assignment processes. In addition, according to different enhancement types, such as @After, @Before, different enhancers need to be created, as shown below:


public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,
        Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,
        MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
    // .... 一些属性的赋值操作
    // A singleton aspect.
    this.pointcut = this.declaredPointcut;
    this.lazy = false;
    this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);

}

The instantiateAdvice method is as follows, which will create different enhancers based on different enhanced annotations:


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

// 创建不同的增强器
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
        MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
    // 获取 Aspect 注解对应的class
    Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
    validate(candidateAspectClass);
    // 再次获取Aspect注解类的所有增强方法来进行判断
    AspectJAnnotation<?> aspectJAnnotation = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
    if (aspectJAnnotation == null) {
        return null;
    }
    // 最终的增强器
    AbstractAspectJAdvice springAdvice;
    // 根据注解类型创建不同的增强器
    switch (aspectJAnnotation.getAnnotationType()) {
        // Pointcut注解 不处理
        case AtPointcut:
            return null;
        case AtAround:
            // around 注解,对应AspectJAroundAdvice增强器
            springAdvice = new AspectJAroundAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
            break;
        case AtBefore:
            // Before注解,对应AspectJMethodBeforeAdvice增强器
            springAdvice = new AspectJMethodBeforeAdvice(
                    candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
            break;
        case AtAfter:
           // After注解,对应AspectJAfterAdvice增强器
            springAdvice = new AspectJAfterAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
            break;
        case AtAfterReturning:
             // AfterReturning注解,对应AfterReturning增强器
            springAdvice = new AspectJAfterReturningAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
            AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
            // 设置返回值
            if (StringUtils.hasText(afterReturningAnnotation.returning())) {
                springAdvice.setReturningName(afterReturningAnnotation.returning());
            }
            break;
        case AtAfterThrowing:
            // AtAfterThrowing注解,对应AspectJAfterThrowingAdvice增强器
            springAdvice = new AspectJAfterThrowingAdvice(
                    candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
            AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
            // 设置对应的异常
            if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
                springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
            }
            break;
        default:
            throw new UnsupportedOperationException(
                    "Unsupported advice type on method: " + candidateAdviceMethod);
    }

    // 对获取到增强器进行一些配置
    springAdvice.setAspectName(aspectName);
    springAdvice.setDeclarationOrder(declarationOrder);
    String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
    if (argNames != null) {
        springAdvice.setArgumentNamesFromStringArray(argNames);
    }
    springAdvice.calculateArgumentBindings();

    return springAdvice;
}

Next look at the implementation of the enhancer:

The enhancer AspectJMethodBeforeAdvice corresponding to the @Before annotation:


springAdvice = new AspectJMethodBeforeAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);

public class AspectJMethodBeforeAdvice extends AbstractAspectJAdvice implements MethodBeforeAdvice, Serializable {

    public AspectJMethodBeforeAdvice(Method aspectJBeforeAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {
        super(aspectJBeforeAdviceMethod, pointcut, aif);
    } 
    // before 方法
    @Override
    public void before(Method method, Object[] args, @Nullable Object target) throws Throwable {
        invokeAdviceMethod(getJoinPointMatch(), null, null);
    }
    // .......
}
// invokeAdviceMethod 方法
protected Object invokeAdviceMethod(JoinPointMatch jpMatch, @Nullable Object returnValue, @Nullable Throwable ex){
        return invokeAdviceMethodWithGivenArgs(argBinding(getJoinPoint(), jpMatch, returnValue, ex));
}
// invokeAdviceMethodWithGivenArgs 方法:
protected Object invokeAdviceMethodWithGivenArgs(Object[] args) throws Throwable {
    Object[] actualArgs = args;
    if (this.aspectJAdviceMethod.getParameterCount() == 0) {
        actualArgs = null;
    }
    ReflectionUtils.makeAccessible(this.aspectJAdviceMethod);
    // 激活增强方法
    return this.aspectJAdviceMethod.invoke(this.aspectInstanceFactory.getAspectInstance(), actualArgs);

}

The above-mentioned different types of enhancers are all subclasses of AbstractAspectJAdvice, and will eventually deactivate the enhancement method in the invokeAdviceMethod method of this class.

The above method logic has completed the analysis of all enhancers, but for all enhancers, they are not necessarily applicable to the current bean, so you need to select a suitable enhancer.

This is the second step of the above findEligibleAdvisors method, the findAdvisorsThatCanApply method:


protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
    // 获取所有增强
    List<Advisor> candidateAdvisors = findCandidateAdvisors();
    // 获取所有增强中适用于 bean 的增强并应用
    List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
    // 对增强进行扩展和排序
    extendAdvisors(eligibleAdvisors);
    if (!eligibleAdvisors.isEmpty()) {
        eligibleAdvisors = sortAdvisors(eligibleAdvisors);
    }
    return eligibleAdvisors;
}

findAdvisorsThatCanApply 方法:


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

    ProxyCreationContext.setCurrentProxiedBeanName(beanName);
    try {
        // 过滤已经得到的 advisors
        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();
    for (Advisor candidate : candidateAdvisors) {
        if (candidate instanceof IntroductionAdvisor) {
            // 上面已经处理过了
            continue;
        }
        if (canApply(candidate, clazz, hasIntroductions)) {
            eligibleAdvisors.add(candidate);
        }
    }
    return eligibleAdvisors;
}

The main function of findAdvisorsThatCanApply is to determine whether the enhancement is applicable to the current bean based on the beanClass and method enhancements. The corresponding method is canAppley(), as follows:


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 {
        return true;
    }
}

public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
    // 不匹配,直接返回
    if (!pc.getClassFilter().matches(targetClass)) {
        return false;
    }
    MethodMatcher methodMatcher = pc.getMethodMatcher();
    if (methodMatcher == MethodMatcher.TRUE) {
        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;
}

The above is the enhanced analysis of Spring AOP, which includes the analysis of the Aspect annotation class and the analysis of all enhanced methods under this class.

to sum up

Spring AOP function, the corresponding analysis class implements the BeanPostProcessor interface, which allows us to perform some operations on the bean before bean initialization. For annotated AOP, before instantiating the AnnotationAwareAspectJAutoProxyCreator bean, it will resolve the Aspect annotated class. As well as all the enhancement methods under this class, each enhancement method corresponds to an Advisor. When the advisor is obtained by analyzing the enhancement method, different enhancers will be created according to the different annotation types of the method.

The above mainly introduces how to obtain the enhancer corresponding to the bean. We know that Spring AOP is implemented through dynamic proxy. After obtaining the enhancer, you can create the corresponding proxy. About the creation of the proxy, the next article will introduce .

Guess you like

Origin blog.51cto.com/15077536/2608535