美文网首页Spring 学习笔记我爱编程
Spring AOP XML配置和注解配置 总结学习

Spring AOP XML配置和注解配置 总结学习

作者: jwfy | 来源:发表于2018-02-17 00:13 被阅读37次

    在前面的三篇中分别介绍了AOP的两种使用方法和具体的源码学习,现在来总结一下这两种方法的同异以及一些之前未注意的细节。

    对象实例化差异

    XML配置扫描到<aop:config>就会创建生成AspectJAwareAdvisorAutoProxyCreator对象,而注解配置在扫描到<aop:aspectj-autoproxy />则创建生成AnnotationAwareAspectJAutoProxyCreator对象,如下图两个类的UML图,注解的类是又扩展了一些属性以及功能。

    image.png
    public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator {
    
        private List<Pattern> includePatterns;
        // 正则匹配的类名称,放在aop:include元素中,扩展实现对合适名称的判断
        // 关注isEligibleBean方法(从函数名称也可以看出判断是否是合适的bean)
    
        private AspectJAdvisorFactory aspectJAdvisorFactory;
        // advisor的工厂
    
        private BeanFactoryAspectJAdvisorsBuilder aspectJAdvisorsBuilder;
        
        protected List<Advisor> findCandidateAdvisors() {
            List<Advisor> advisors = super.findCandidateAdvisors();
            advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
            // 拓展了找出所有合适的advisor的方法,也恰好体现了两种注解方式的真正差异的地方
            return advisors;
        }
      ...
    

    获取PointCut、advisor信息差异

    这点差异在XML配置的源码学习和注解配置的源码学习中都已经介绍清楚了,现在总结下

    • XML配置中详细解析XML的各个节点数据,不管是pointCut还是advisor,都会生产一个beandefinition,会以#+序号为beanName的结尾名称。
    • 注解配置会先扫描beandefinition集合中所有类型为Object的beandefinition集合,通过includePatterns参数进行正则的匹配,过滤出合适的beandefinition的bean,过滤出注解为@Aspect的bean,扫描bean的所有方法存储到cache中

    扫描beandefinition集合过滤操作只会执行一次!
    执行的结果会存储到cache中,便于后面每次执行

    两种的差异在于注解配置只会产生一个beandefinition,然后所有的AOP信息都会存储在该beandefinition实例化的对象中,而XML则会每个AOP配置都会映射到一个beandefinition,后续每个beandefinition绑定和自己关联的AOP信息

    排序规则

    两种方法的排序规则调用位置是一致的,而且排序规则也是完全一样的(公用同一套代码逻辑)

    AbstractAdvisorAutoProxyCreator 文件

    protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
        List<Advisor> candidateAdvisors = findCandidateAdvisors();
        List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
        extendAdvisors(eligibleAdvisors);
        if (!eligibleAdvisors.isEmpty()) {
           // 这个sort就是决定了advisor的排序
            eligibleAdvisors = sortAdvisors(eligibleAdvisors);
        }
        return eligibleAdvisors;
    }
    
    protected List<Advisor> sortAdvisors(List<Advisor> advisors) {
        AnnotationAwareOrderComparator.sort(advisors);
        // 该类是继承Comparator,实现自定义的排序
        // 就AOP排序来说,是根据各个类的declarationOrder进行排序的
        // PS:该bean排序在spring中被广泛使用
        return advisors;
    }
    

    AOP中几种advisor的默认declarationOrder值情况如下表,需要注意到这个规则和严格的执行顺序不一样,真正执行的时候ProxyFactory还需要进行wrap处理。

    类名称 declarationOrder值 说明
    AspectJAfterThrowingAdvice 9 afterThrow
    AspectJAfterReturningAdvice 7 afterReturn
    AspectJMethodBeforeAdvice 5 methodBefore
    AspectJAroundAdvice 3 around
    AspectJAfterAdvice 1 after

    相关文章

      网友评论

        本文标题:Spring AOP XML配置和注解配置 总结学习

        本文链接:https://www.haomeiwen.com/subject/qyhmtftx.html