资讯专栏INFORMATION COLUMN

基于AspectJ的Spring AOP Advice执行顺序

xinhaip / 2940人阅读

摘要:前言用过做过开发的同学多少都对的有所了解和使用的经验也都知道有等至于的基本概念我想大家也都清楚这里也就不再赘述今天在论坛里看到了一个问题谈到了的执行顺序的问题看到问题以后突然发现自己对这方面的理解也不是十分的深入在回答问题的同时正好对这个知

前言

用过Spring做过开发的同学,多少都对Spring的AOP有所了解和使用的经验.也都知道有@Around,@Before,@After等Advice.至于Spring AOP的基本概念,我想大家也都清楚,这里也就不再赘述.

今天在论坛里看到了一个问题,谈到了Spring AOP的Advice执行顺序的问题,看到问题以后,突然发现自己对这方面的理解也不是十分的深入.在回答问题的同时,正好对这个知识点深入的了解一下.

本文基于Spring AspectJ AOP的方式来进行描述.

Spring官方对Advice执行顺序的解释

参考文档:aop-ataspectj-advice-ordering

When two pieces of advice defined in different aspects both need to run at the same join point, unless you specify otherwise the order of execution is undefined. You can control the order of execution by specifying precedence. This is done in the normal Spring way by either implementing the org.springframework.core.Ordered interface in the aspect class or annotating it with the Order annotation. Given two aspects, the aspect returning the lower value from Ordered.getValue() (or the annotation value) has the higher precedence.

上面的内容简单的说就是,当对于同一个Join Point有两个Advice定义在不同的Aspect中的时候,他们的执行顺序是根据Aspect类的@Order注解的值,或者通过实现Order并重写getValue方法的值来决定的.同时,Order的值越小,优先级越高.

When two pieces of advice defined in the same aspect both need to run at the same join point, the ordering is undefined

当同一个Aspect中对同一个Join Point有两个Advice的话,这两个Advice的顺序是不固定的.

实例

首先我们建立一个Spring的工程,然后基于spring-test进行下面的操作.本文的spring版本是:4.3.11.RELEASE

1. 建立一个AuthAnnotation注解类,该注解作用在方法上即可

2. 在spring的配置中添加aspect aop支持

3. 编写Aspect的Advice,请注意图一红框的方法名


4. 编写一个Service,符合上面的切入点规则即可

5. 执行单元测试,调用TestService.test()方法,输出结果如下

----Order1:checkAuth:Annotation----
----Order1:checkAuthPackage:Execution----
----Order2:checkAuthPackage:Execution----
---Service:Test---

多次运行以后,我们会发现一个问题,就是Order1的checkAuth方法一直是第一个执行.这是不是说明,以注解方式的PointCut是不是会有首先执行的优先级?
如果是的话,这就不符合上面Spring官方文档的说法了.来让我们看看为什么?

ReflectiveAspectJAdvisorFactory

该类的作用是基于AspectJ时,创建Spring AOP的Advice.

static {
        CompoundComparator comparator = new CompoundComparator();
        comparator.addComparator(new ConvertingComparator(
                new InstanceComparator(
                        Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class),
                new Converter() {
                    @Override
                    public Annotation convert(Method method) {
                        AspectJAnnotation annotation =
                                AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(method);
                        return (annotation != null ? annotation.getAnnotation() : null);
                    }
                }));
        comparator.addComparator(new ConvertingComparator(
                new Converter() {
                    @Override
                    public String convert(Method method) {
                        return method.getName();
                    }
                }));
        METHOD_COMPARATOR = comparator;
    }

从该类的静态方法块中我们可以看到,Advice列表的添加顺序是按照Around/Before/After/AfterReturning/AfterThrowing的顺序,同时根据Advice的方法名顺序进行排序的.

当调用到getAdvisors方法的时候,会调用getAdvisorMethods方法,来获取所有的advice Method对象.同时根据METHOD_COMPARATOR的规则进行排序.

最后的测试

我们修改OrderOneAspect这个类中,checkAuthPackage方法的名字为aCheckAuthPackage,在执行一次单元测试的结果如下:

----Order1:checkAuthPackage:Execution----
----Order1:checkAuth:Annotation----
----Order2:checkAuthPackage:Execution----
---Service:Test---

输出的结果中,我们可以看到,优先执行的不再是注解方式的PonitCut.由此可见,当同一个Aspect中对同一个Join Point有两个Advice的话,执行的顺序与方法的名称有关.

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/70490.html

相关文章

  • Learn Spring - Spring AOP

    摘要:下例表示方法入参为的方法匹配该切点,并将和两个参数绑定到切面方法的入参中绑定代理对象使用或可以绑定被代理对象的实例。 1. 术语 连接点(JointPoint):代码中具有边界性质特定点;Spring仅支持方法的连接点,包含方法和方位两方面信息 切点(Pointcut):定位到某个方法 增强(Advice):织入到目标连接点上的代码 目标对象(Target):增强逻辑的目标织入类 引...

    kgbook 评论0 收藏0
  • 慕课网_《Spring入门篇》学习总结

    摘要:入门篇学习总结时间年月日星期三说明本文部分内容均来自慕课网。主要的功能是日志记录,性能统计,安全控制,事务处理,异常处理等等。 《Spring入门篇》学习总结 时间:2017年1月18日星期三说明:本文部分内容均来自慕课网。@慕课网:http://www.imooc.com教学示例源码:https://github.com/zccodere/s...个人学习源码:https://git...

    Ververica 评论0 收藏0
  • 从动态代理到SpringAop以及AspectJ风格

    摘要:具体的动态代理运行原理这里暂不展开,网上有很多相关的内容,比如这篇翻译过来就是面向方面切面编程。所以切面可以理解为和的集合。 1.静态代理 在提及动态代理前先说明一下静态代理模式,静态代理模式是一种很常见的通用设计模式,实现也很简单,uml类图如下: showImg(https://segmentfault.com/img/bVba3gn?w=737&h=312); 如上图所示,代理类...

    msup 评论0 收藏0
  • 彻底征服 Spring AOP 之 理论篇

    摘要:基本知识其实接触了这么久的我感觉给人难以理解的一个关键点是它的概念比较多而且坑爹的是这些概念经过了中文翻译后变得面目全非相同的一个术语在不同的翻译下含义总有着各种莫名其妙的差别鉴于此我在本章的开头着重为为大家介绍一个的各项术语的基本含义为了 基本知识 其实, 接触了这么久的 AOP, 我感觉, AOP 给人难以理解的一个关键点是它的概念比较多, 而且坑爹的是, 这些概念经过了中文翻译后...

    Kylin_Mountain 评论0 收藏0
  • Spring AOP 入门

    摘要:一以及术语是的简称,被译为面向切面编程。切面由切点和增强组成,他包括了连接点定义和横切逻辑代码的定义,就是负责实施切面的框架。五使用来定义纯粹的切面使用方法也非常简单,使用的标签。采用动态代理和动态代理技术在运行期间织入。 引言 AOP是软件开发思想发展到一定阶段的产物,AOP的出现并不是为了代替OOP,仅作为OOP的有益补充,在下面的例子中这个概念将会得到印证。AOP的应用场合是受限...

    CodeSheep 评论0 收藏0

发表评论

0条评论

xinhaip

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<