关于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. Python中eval函数的作用

    eval eval函数就是实现list.dict.tuple与str之间的转化str函数把list,dict,tuple转为为字符串# 字符串转换成列表a = "[[1,2], [3,4], ...

  2. (二叉树 递归) leetcode 889. Construct Binary Tree from Preorder and Postorder Traversal

    Return any binary tree that matches the given preorder and postorder traversals. Values in the trave ...

  3. nginx日志格式定义和nginx.conf配置模板说明

    在http的功能里添加log_format模块,内容如下: log_format main escape=json '{ "@timestamp": "$time_iso ...

  4. <03>labview在winCE6.0系统下的程序移植与界面开发

    任务布置:labview与winCE开发<3> 要求一:学会TouchPane的环境配置,建立调试通道:要求二:掌握触控屏幕界面优化: 正文: 今天介绍labview虚拟仪器软件中 Tou ...

  5. C语言的函数指针数组(好绕啊~看完这篇估计就通关了)

    转自https://www.cnblogs.com/chr-wonder/p/5168858.html int *(*p(int))[3] 今天有人问这个是啥?我一看直接就懵逼了…… 下面做一些简单的 ...

  6. OA系统开发人事模块关于请假跨月的处理

    前言:其实对于跨月的数据单独处理是不难的,但是对于后台显示页面,肯定不是单纯拼接一个where条件的,因此在我的项目也是如此,并不能够用普遍的方法来处理,此时就想尽量用简单的方法来处理跨月数据的准确性 ...

  7. 当前标识没有对“C:\WINDOWS\Microsoft.NET\...”的写访问权限的解决办法

    1.需要重新注册IIS服务扩展,在开始运行中输入以下命令运行:aspnet_regiis -i 32位的Windows: --------------------------------------- ...

  8. mybatis中 keyProperty="id" 的作用

    keyProperty="id"的作用是: 一般都是结合数据库自动生成主键来使用,由于是数据库生成的主键, 所以在这个对象持久化到数据库之前是对象中的这个属性是没有属性值的,但是在 ...

  9. go语言圣经练习

    练习 3.10: 编写一个非递归版本的comma函数,使用bytes.Buffer代替字符串链接操作. package main import ( "fmt" "os&q ...

  10. vue 点击展开显示更多 点击收起部分隐藏

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...