Análise do código-fonte do método de anotação Spring AOP

Análise do código-fonte do método de anotação Spring AOP

Programação da tecnologia TSMYK Java

Prefácio

No último artigo, Explicação detalhada do uso da função Spring AOP, aprendi um uso detalhado do Sprig AOP. Agora vamos ver como ele é implementado no Spring.

aspectj-autoproxy

Nós sabemos que se você quiser usar Spring AOP, você deve primeiro adicionar o item de configuração <aop: aspectj-autoproxy expose-proxy = "true" proxy-target-class = "true" /> no arquivo de configuração, e os dois atributos são opcionais. Para cada tag no Spring, há um analisador correspondente para análise, e para tags aspectj-autoproxy, o analisador AspectJAutoProxyBeanDefinitionParser é usado para análise, conforme mostrado abaixo:


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

Existem duas funções principais em AspectJAutoProxyBeanDefinitionParser. Uma é registrar o bean AnnotationAwareAspectJAutoProxyCreator e a outra é analisar os dois atributos de <aop: aspectj-autoproxy />. Entre eles, a função AOP é basicamente feita por AnnotationAwareAspectJAutoProxyCreator;

Registrar AnnotationAwareAspectJAutoProxyCreator

Todos os analisadores implementam a interface BeanDefinitionParser e a entrada é analisada a partir do método de análise. O método de análise de AspectJAutoProxyBeanDefinitionParser é o seguinte:


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

O método AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary é o seguinte:


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

Neste método, três funções são principalmente concluídas, e cada linha de código completa uma função:

  1. Registrar AnnotationAwareAspectJAutoProxyCreator
  2. Processando atributos expose-proxy e proxy-target-class
  3. Registrar componentes e notificar

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

Processando atributos expose-proxy e proxy-target-class


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

Neste ponto, o registro de AnnotationAwareAspectJAutoProxyCreator é concluído. Conforme mencionado acima, as funções de AOP são basicamente concluídas por AnnotationAwareAspectJAutoProxyCreator. A seguir, vamos dar uma olhada em como essa classe completa as operações de AOP.

Analisar Advce

Vamos dar uma olhada no diagrama de classes de AnnotationAwareAspectJAutoProxyCreator da seguinte maneira:

Análise do código-fonte do método de anotação Spring AOP
Como pode ser visto no diagrama de classe acima, AnnotationAwareAspectJAutoProxyCreator implementa BeanPostProcessor, e o bean desta interface é implementado no Spring. Quando o Spring carrega o bean, ele chama seu método postProcessAfterInitializatio antes da inicialização; o método postProcessAfterInitialization da classe pai AbstractAutoxyCreator é implementado do seguinte modo:


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

A partir do código acima, podemos ver que o aprimoramento de AOP será analisado antes de instanciar AnnotationAwareAspectJAutoProxyCreator. Depois que a análise for aprimorada, o proxy aprimorado será criado; este artigo examinará primeiro a aquisição aprimorada e a criação do proxy será feito no próximo artigo explicar.

Melhore

Obtenha todas as suas melhorias de acordo com a classe correspondente do bean e beanName, para o método 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;
}

O método para obter todas as melhorias findCandidateAdvisors () Depois de muitos julgamentos lógicos complicados, a aquisição aprimorada de AOP e a análise de expressões de pointcut são implementadas dentro deste método:


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

Obtenha o aprimoramento de anotação do bean, correspondendo ao método this.aspectJAdvisorsBuilder.buildAspectJAdvisors (), encontre todos os beans anotados AspectJ, para cada método de aprimoramento, um Advisor correspondente será criado, ou seja, um método para um 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;
}

O método acima concluiu a extração do Advisor e a aquisição do realçador é entregue ao método advisorFactory.getAdvisors (), da seguinte forma:


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

Obtenção de realçadores comuns

O realçador normal é obtido por meio do método getAdvisor (), que inclui a aquisição de anotações de pointcut e o aprimoramento da geração de informações de anotação, como segue:


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

Obter informações do ponto de corte 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;
    }
}

Depois que o método acima obtém as informações de pointcut específicas, ele irá gerar o realçador correspondente de acordo com as informações de pointcut. Cada informação de pointcut como @After, @Before corresponde a um objeto InstantiationModelAwarePointcutAdvisorImpl, como segue:


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

No processo de instanciar o objeto, existem alguns processos de atribuição. Além disso, de acordo com diferentes tipos de aprimoramento, como @After, @Before, diferentes aprimoradores precisam ser criados, conforme mostrado abaixo:


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

}

O método instantiateAdvice é o seguinte, que criará diferentes realçadores com base em diferentes anotações aprimoradas:


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

Em seguida, observe a implementação do intensificador:

O realçador AspectJMethodBeforeAdvice correspondente à anotação @Before:


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

}

Os diferentes tipos de realçadores mencionados acima são todas subclasses de AbstractAspectJAdvice e, eventualmente, desativarão o método de aprimoramento no método invokeAdviceMethod desta classe.

A lógica do método acima concluiu a análise de todos os intensificadores, mas para todos os intensificadores, não necessariamente aplicáveis ​​ao bean atual, portanto, você precisa selecionar um intensificador adequado.

Esta é a segunda etapa do método findEligibleAdvisors acima, o método findAdvisorsThatCanApply:


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

A função principal de findAdvisorsThatCanApply é determinar se o aprimoramento é aplicável ao bean atual com base no beanClass e nos aprimoramentos do método. O método correspondente é canAppley (), como segue:


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

O texto acima é a análise aprimorada do Spring AOP, que inclui a análise da classe de anotação Aspect e a análise de todos os métodos aprimorados dessa classe.

Resumindo

A função Spring AOP, a classe de análise correspondente implementa a interface BeanPostProcessor, que nos permite realizar algumas operações no bean antes da inicialização do bean. Para AOP anotado, antes de instanciar o bean AnnotationAwareAspectJAutoProxyCreator, ele resolverá a classe anotada Aspect. Bem como todos os métodos de aprimoramento nesta classe, cada método de aprimoramento corresponde a um Consultor. Quando o orientador é obtido pela análise do método de aprimoramento, diferentes aprimoradores serão criados de acordo com os diferentes tipos de anotação do método.

A descrição acima apresenta principalmente como obter o realçador correspondente ao bean. Sabemos que Spring AOP é implementado por meio de proxy dinâmico. Após obter o realçador, você pode criar o proxy correspondente. Sobre a criação do proxy, o próximo artigo apresentará.

Acho que você gosta

Origin blog.51cto.com/15077536/2608535
Recomendado
Clasificación