关于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. MySql数据库字段排序规则不一致产生的一个问题

    最近项目向MySql迁移,迁移完毕后,在获取用户权限时产生了一个异常,跟踪进去获取执行的语句如下, SELECT PermissionId FROM spysxtPermission WHERE (R ...

  2. 《STL源码剖析》----2.23 value_type()和__type_traits<>如何实现

    在2.13小节destory()第二版本接受两个迭代器找出元素类型,代码如下 其中value_type()判断出类型,__type_traits判断是否存在trivial destructor 在3. ...

  3. Python成绩

    # -*- coding: utf-8 -*- """ Spyder Editor This is a temporary script file. "&quo ...

  4. Linux命令_sed_2

    2.替换(将包含"xxx"的行中的"yyy"替换成"zzz") 现有文件“replace_specified_contained_line” ...

  5. Ubuntu16.04安装及配置nginx

    Nginx ("engine x") 是一个高性能的 HTTP 和 反向代理 服务器,也是一个 IMAP/POP3/SMTP 代理服务器. Nginx 是由 Igor Sysoev ...

  6. Form 表单相关小技巧

    JS ---textarea 高度自适应 var realH = this.scrollHeight + 10+ "px"; $(this).css("height&qu ...

  7. react图工具集成

    背景 调查了react下的图工具库, 并继承到项目中, 经过调研列出如下两个图工具库,可以同时使用. data-ui react-c3js 在一个工具中没有所需的图时候, 可以使用另一个替代. dat ...

  8. idea中pom.xml添加了新的maven依赖,点击import changes没反应

    打开file,setting. 选择Build,Execution,Deployment -> Build Tools -> Maven. 修改maven home directory为自 ...

  9. 简单文本悬浮div提示效果

    <html> <head> <script src="jquery-1.9.1.min.js" type="text/javascript& ...

  10. react项目构建

    1.react脚手架 npm install -g create-react-app create-react-app myproject 2.页面配置(bootcdn) <script src ...