关于spring aop Advisor排序问题

当我们使用多个Advisor的时候有时候需要排序,这时候可以用注解org.springframework.core.annotation.Order或者实现org.springframework.core.Ordered接口。

示例代码:

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order; /**
* @author yaojiafeng
* @create 2017-09-11 下午3:32
*/
@Aspect
@Order(1)
public class LogAspect implements Ordered { Logger logger = LoggerFactory.getLogger(LogAspect.class); @Pointcut("@annotation(com.yaojiafeng.test.aop.LogMDC)")
public void log() { } @Around("log()")
public Object log(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
String interfaceName = proceedingJoinPoint.getTarget().getClass().getName();
String methodName = proceedingJoinPoint.getSignature().getName();
Object[] args = proceedingJoinPoint.getArgs();
Object obj = null;
try {
obj = proceedingJoinPoint.proceed();
} finally {
logger.info(interfaceName + "-" + methodName + "-" + obj + "-" + args);
}
return obj;
} @Override
public int getOrder() {
return 1;
}
}

spring aop会在AnnotationAwareAspectJAutoProxyCreator处理bean查找到适配的Advisor的时候对所有Advisor进行排序并生成动态代理,AspectJAwareAdvisorAutoProxyCreator的sortAdvisors方法

@Override
@SuppressWarnings("unchecked")
protected List<Advisor> sortAdvisors(List<Advisor> advisors) {
List<PartiallyComparableAdvisorHolder> partiallyComparableAdvisors =
new ArrayList<PartiallyComparableAdvisorHolder>(advisors.size());
for (Advisor element : advisors) {
partiallyComparableAdvisors.add(
new PartiallyComparableAdvisorHolder(element, DEFAULT_PRECEDENCE_COMPARATOR));
}
List<PartiallyComparableAdvisorHolder> sorted =
PartialOrder.sort(partiallyComparableAdvisors);
if (sorted != null) {
List<Advisor> result = new ArrayList<Advisor>(advisors.size());
for (PartiallyComparableAdvisorHolder pcAdvisor : sorted) {
result.add(pcAdvisor.getAdvisor());
}
return result;
}
else {
return super.sortAdvisors(advisors);
}
}

这里会根据每个Advisor的获取到的order值进行从小到大排序,order值获取规则如下:

  1. 首先判断当前Advisor所在的切面类是否实现org.springframework.core.Ordered接口,是的话调用getOrder方法获取
  2. 否则判断当前Advisor所在的切面类是否包含org.springframework.core.annotation.Order注解,是的话从注解获取
  3. 没有取到值,默认为最低优先级,值为最大Int

从排序代码可知,有以下处理过程:

  1. 打在Advice方法上的org.springframework.core.annotation.Order注解不予识别
  2. 如果一个切面类存在多个Advisor,则会按Advice方法的声明顺序,声明在前的优先级高,先执行
  3. 不同切面类但是order值是一样的,则按spring获取到切面bean的顺序做排序,先获取先执行

关于spring aop Advisor排序问题的更多相关文章

  1. 框架源码系列三:手写Spring AOP(AOP分析、AOP概念学习、切面实现、织入实现)

    一.AOP分析 问题1:AOP是什么? Aspect Oriented Programming 面向切面编程,在不改变类的代码的情况下,对类方法进行功能增强. 问题2:我们需要做什么? 在我们的框架中 ...

  2. Spring Aop(十四)——Aop自动创建代理对象的原理

    转发地址:https://www.iteye.com/blog/elim-2398725 Aop自动创建代理对象的原理 我们在使用Spring Aop时,通常Spring会自动为我们创建目标bean的 ...

  3. spring Aop中aop:advisor 与 aop:aspect的区别

    转载:http://blog.csdn.net/u011710466/article/details/52888277 在spring的配置中,会用到这两个标签.那么他们的区别是什么呢?       ...

  4. Spring AOP Example – Pointcut , Advisor

    In last Spring AOP advice examples, the entire methods of a class are intercepted automatically. But ...

  5. spring 中的<aop:advisor>和<aop:aspect>的区别

    在AOP中有几个概念: — 方面(Aspect):一个关注点的模块化,这个关注点实现可能另外横切多个对象.事务管理是J2EE应用中一个很好的横切关注点例子.方面用Spring的Advisor或拦截器实 ...

  6. Spring AOP高级——源码实现(2)Spring AOP中通知器(Advisor)与切面(Aspect)

    本文例子完整源码地址:https://github.com/yu-linfeng/BlogRepositories/tree/master/repositories/Spring%20AOP%E9%A ...

  7. 利用cglib包实现Spring中aop的<aop:advisor>功能

    一:前言 还有<aop:before>/<aop:after>/<aop:around>的没有实现,不过根<aop:advisor>是差不多的,就是要额 ...

  8. Spring学习(十六)----- Spring AOP实例(Pointcut(切点),Advisor)

    在上一个Spring AOP通知的例子,一个类的整个方法被自动拦截.但在大多数情况下,可能只需要一种方式来拦截一个或两个方法,这就是为什么引入'切入点'的原因.它允许你通过它的方法名来拦截方法.另外, ...

  9. spring错误处理 Build path is incomplete. Cannot find class file for org.springframework.aop.Advisor

    Build path is incomplete. Cannot find class file for org.springframework.aop.Advisor 初学spring,记录一下出现 ...

随机推荐

  1. 【洛谷P3014】Cow Line

    题目大意:康托展开和逆康托展开模板题. 题解: 注:20!约为 2e18. 代码如下 #include <bits/stdc++.h> using namespace std; const ...

  2. 关于 redis 的 数据类型 和 内存模型

    该文章 是在读了 公众号 : java 后端技术 之后 做的一个小记录 原文网址  : https://mp.weixin.qq.com/s/mI3nDtQdlVlLv2uUTxJegA 作者文章写的 ...

  3. [图解Java]Condition

    图解Condition 0. demo 我先给出一个demo, 这样大家就可以根据我给的这段代码, 边调试边看源码了. 还是那句话: 注意"My" , 我把ReentrantLoc ...

  4. 背包九讲PDF

    本资料仅限个人学习交流使用,不得用于商业用途. 背包九讲PDF:https://pan.baidu.com/s/17rTxMwCo9iSTOW77yucdXQ   提取码:xbqa

  5. react native头部标题样式修改

    navigationOptions: ({navigation}) => ({ headerTitle:'评估记录', headerBackTitle:null, headerLeft:null ...

  6. C#匿名对象(转JSON)

    多类型匿名对象 var result = new { pages = , users = new System.Collections.ArrayList { ,name="}, ,name ...

  7. important覆盖行内样式

    优先级,外部样式<内部样式<行内样式,后台富文本编辑器编辑的正文显示在前台时可用!important覆盖其行内样式 今天的问题,font-family:"思源黑体 CN!impo ...

  8. 基于Python的Webservice开发(一)-简介

    之前为了解决Webservice的开发,直接用Python自带的CGI模块挂在IIS上. 但是该方式开发Soap的接口,需要大量的开发,而且安全方面也存在很多问题. 我推荐关于用Python开发Web ...

  9. 机器学习基石11-Linear Models for Classification

    注: 文章中所有的图片均来自台湾大学林轩田<机器学习基石>课程. 笔记原作者:红色石头 微信公众号:AI有道 上一节课,我们介绍了Logistic Regression问题,建立cross ...

  10. 7zip,命令行解压报错:7-Zip cannot find the code that works with archives.

    简单的命令: 7z x zipfile.7z 7-Zip 9.20 Copyright (c) 1999-2010 Igor Pavlov 2010-11-18 Error: 7-Zip cannot ...