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的顺序做排序,先获取先执行
  • 相关阅读:
    你眼中的程序员 VS 程序员眼中的自己,是时候打破代沟了
    GaussDB(for openGauss)让数据“存得下、算得快、算得准”
    初识GaussDB(for Cassandra)
    云原生势不可挡,华为云GaussDB加速企业数字化转型
    HDC.Cloud2021|开发者们都在谈的云原生到底长什么样?
    基于深度神经网络的噪声标签学习
    华为云PB级数据库GaussDB(for Redis)揭秘第七期:高斯Redis与强一致
    Delphi 窗体函数GetActiveWindow
    Delphi 窗体函数GetWindowText -获取窗口的标题
    深度学习数据预处理
  • 原文地址:https://www.cnblogs.com/yaojf/p/9877994.html
Copyright © 2011-2022 走看看