关于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;}@Overridepublic 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值获取规则如下:
- 首先判断当前Advisor所在的切面类是否实现org.springframework.core.Ordered接口,是的话调用getOrder方法获取
- 否则判断当前Advisor所在的切面类是否包含org.springframework.core.annotation.Order注解,是的话从注解获取
- 没有取到值,默认为最低优先级,值为最大Int
从排序代码可知,有以下处理过程:
- 打在Advice方法上的org.springframework.core.annotation.Order注解不予识别
- 如果一个切面类存在多个Advisor,则会按Advice方法的声明顺序,声明在前的优先级高,先执行
- 不同切面类但是order值是一样的,则按spring获取到切面bean的顺序做排序,先获取先执行