zoukankan      html  css  js  c++  java
  • 关于spring aop Advisor排序问题

    关于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的顺序做排序,先获取先执行
  • 相关阅读:
    php计算utf8字符串长度
    php和js字符串的acsii码函数
    快速排序的php实现
    bzoj 2822 [AHOI2012]树屋阶梯 卡特兰数
    bzoj 1485 [HNOI2009]有趣的数列 卡特兰数
    bzoj 4173 打表???
    bzoj [Noi2002]Savage 扩展欧几里得
    bzoj 3505 [Cqoi2014]数三角形 组合
    bzoj 2820 莫比乌斯反演
    Travel 并查集
  • 原文地址:https://www.cnblogs.com/yaojf/p/9877994.html
Copyright © 2011-2022 走看看