Spring 如何保证后置处理器的执行顺序 - OrderComparator
Spring 如何保证后置处理器的执行顺序 - OrderComparator
Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.html)
一、JDK 自带的比较器 Comparator
1.1 Comparable
Integer 内部实现了 Comparable 接口
public final class Integer extends Number implements Comparable<Integer> {
public int compareTo(Integer anotherInteger) {
return compare(this.value, anotherInteger.value);
}
public static int compare(int x, int y) {
return (x < y) ? -1 : ((x == y) ? 0 : 1);
}
}
这样就可以用集合或数组工具进行排序,不需要再定义比较器了。
@Test
public void test() {
// 1. 集合排序
List<Integer> integerList = Arrays.asList(3, 2, 1, 5, 6);
// integerList.sort()
Collections.sort(integerList);
Assert.assertEquals(Arrays.asList(1, 2, 3, 5, 6), integerList);
// 2. 数组排序
Arrays.sort(new Integer[]{3, 2, 1, 5, 6});
}
1.2 Comparator
还在另外一种情况,需要排序的对象没有实现 Comparable,那怎么办呢?JDK 提供了一个专门的比较器 Comparator。
@FunctionalInterface
public interface Comparator<T> {
// o1>o2: 1; o1=o2: 0;o1<o2: -1;
// Assert.assertEquals(-1, Integer.compare(1, 2));
int compare(T o1, T o2);
}
Collections 集合对应的排序方式如下:
public static <T> void sort(List<T> list, Comparator<? super T> c) {
list.sort(c);
}
二、Spring 中的比较器 OrderComparator
在 Spring 中提供了接口和注解两种方式,注意 Spring 中数值越小级别越高,位于 core 包中:
一是实现 Ordered 或 PriorityOrdered 接口,PriorityOrdered 的级别要优先于 Ordered,使用 OrderComparator 比较器。
二是使用 @Order(Spring 规范) 或 @Priority(JDK 规范) 注解,使用 AnnotationAwareOrderComparator 比较器。
2.1 OrderComparator
2.1.1 Ordered 接口
public interface PriorityOrdered extends Ordered {
}
public interface Ordered {
int HIGHEST_PRECEDENCE = Integer.MIN_VALUE;
int LOWEST_PRECEDENCE = Integer.MAX_VALUE;
int getOrder();
}
2.1.2 OrderComparator
// 实现 JDK 的 Comparator
public class OrderComparator implements Comparator<Object> {
@Override
public int compare(@Nullable Object o1, @Nullable Object o2) {
return doCompare(o1, o2, null);
}
private int doCompare(@Nullable Object o1, @Nullable Object o2, @Nullable OrderSourceProvider sourceProvider) {
boolean p1 = (o1 instanceof PriorityOrdered);
boolean p2 = (o2 instanceof PriorityOrdered);
// 1. PriorityOrdered 接口优先
if (p1 && !p2) {
return -1;
} else if (p2 && !p1) {
return 1;
}
// 2. 比较 getOrder 的值,数值越小越优先
int i1 = getOrder(o1, sourceProvider);
int i2 = getOrder(o2, sourceProvider);
return Integer.compare(i1, i2);
}
}
使用和 JDK 一致。
2.2 AnnotationAwareOrderComparator
AnnotationAwareOrderComparator 继承自 OrderComparator 增加了 @Order(Spring 规范) 或 @Priority(JDK 规范) 注解的处理。
2.2.1 @Order
public @interface Order {
int value() default Ordered.LOWEST_PRECEDENCE;
}
// javax.annotation.Priority
public @interface Priority {
int value();
}
2.2.2 AnnotationAwareOrderComparator
AnnotationAwareOrderComparator 重写了 findOrder,增加了对 @Order 或 @Priority 两个注解的处理。使用 OrderUtils 工具类。
@Override
protected Integer findOrder(Object obj) {
// Check for regular Ordered interface
Integer order = super.findOrder(obj);
if (order != null) {
return order;
}
// Check for @Order and @Priority on various kinds of elements
if (obj instanceof Class) {
return OrderUtils.getOrder((Class<?>) obj);
} else if (obj instanceof Method) {
Order ann = AnnotationUtils.findAnnotation((Method) obj, Order.class);
if (ann != null) {
return ann.value();
}
} else if (obj instanceof AnnotatedElement) {
Order ann = AnnotationUtils.getAnnotation((AnnotatedElement) obj, Order.class);
if (ann != null) {
return ann.value();
}
} else {
order = OrderUtils.getOrder(obj.getClass());
if (order == null && obj instanceof DecoratingProxy) {
order = OrderUtils.getOrder(((DecoratingProxy) obj).getDecoratedClass());
}
}
return order;
}
2.3 测试
有以下 4 个类,分别是实现 PriorityOrdered 接口、实现 Ordered 接口、@Order 注解、普通 bean.
class A implements PriorityOrdered {
@Override
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE;
}
}
class B implements Ordered {
@Override
public int getOrder() {
return 10;
}
}
@Order(0)
class C {
}
class D {
}
测试排序的结果:
@Test
public void test() {
List<Object> list = Arrays.asList(new D(), new C(), new B(), new A());
AnnotationAwareOrderComparator.sort(list);
// A C B D
list.forEach(o -> System.out.print(o.getClass().getSimpleName() + " "));
}
A 实现了 PriorityOrdered 接口排第一位、B 和 C 分别比较 order 值、D 排最后。
每天用心记录一点点。内容也许不重要,但习惯很重要!
Spring 如何保证后置处理器的执行顺序 - OrderComparator的更多相关文章
- Spring之BeanPostProcessor(后置处理器)介绍
为了弄清楚Spring框架,我们需要分别弄清楚相关核心接口的作用,本文来介绍下BeanPostProcessor接口 BeanPostProcessor 该接口我们也叫后置处理器,作用是在Be ...
- Spring点滴五:Spring中的后置处理器BeanPostProcessor讲解
BeanPostProcessor接口作用: 如果我们想在Spring容器中完成bean实例化.配置以及其他初始化方法前后要添加一些自己逻辑处理.我们需要定义一个或多个BeanPostProcesso ...
- spring学习四:Spring中的后置处理器BeanPostProcessor
BeanPostProcessor接口作用: 如果我们想在Spring容器中完成bean实例化.配置以及其他初始化方法前后要添加一些自己逻辑处理.我们需要定义一个或多个BeanPostProcesso ...
- Spring的BeanPostProcessor后置处理器与bean的生命周期
前言 本文将把Spring在Bean的生命周期中涉及到的后置处理器一一梳理出来,并简要说一下功能,至于每个后置处理器在实际扩展中的用处,还要后续慢慢探索总结. 正文 下面一步步跟进探寻那些后置处理器们 ...
- spring中Bean后置处理器实现总结
BeanPostProcessor接口 bean的后置处理器实现功能主要是 可以在bean初始化之前和之后做增强处理.自定义MyBeanProcessor实现BeanPostProcessor接口,重 ...
- Spring Bean前置后置处理器的使用
Spirng中BeanPostProcessor和InstantiationAwareBeanPostProcessorAdapter两个接口都可以实现对bean前置后置处理的效果,那这次先讲解一下B ...
- Spring中的后置处理器BeanPostProcessor讲解
Spring中提供了很多PostProcessor供开发者进行拓展,例如:BeanPostProcessor.BeanFactoryPostProcessor.BeanValidationPostPr ...
- 2.3 spring5源码系列---内置的后置处理器PostProcess加载源码
本文涉及主题 1. BeanFactoryPostProcessor调用过程源码剖析 2. 配置类的解析过程源码 3. 配置类@Configuration加与不加的区别 4. 重复beanName的覆 ...
- [原创]java WEB学习笔记101:Spring学习---Spring Bean配置:IOC容器中bean的声明周期,Bean 后置处理器
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
随机推荐
- 理解JVM2 栈内存,方法区,堆内存
堆,方法区,栈的关系 分配最大堆内存-Xmx32m class SimpleHeap(val id: Int){ fun show() = println("My id is $id&quo ...
- FLAG_ACTIVITY_CLEAR_TASK | FLAG_ACTIVITY_NEW_TASK
[FLAG_ACTIVITY_CLEAR_TASK | FLAG_ACTIVITY_NEW_TASK] 1.FLAG_ACTIVITY_NEW_TASK 2.FLAG_ACTIVITY_CLEAR_T ...
- msf客户端渗透(四):关闭UAC,hash、防火墙、服务、磁盘、DEP、防病毒、远程桌面、桌面截图、获取tooken
关闭UAC 如果你获得一个system权限的session 进入到这个session 进入到shell 依次输入以下命令 cmd.exe /k %windir%\System32\reg.exe AD ...
- python使用函数作为参数
在实际使用中,我们有时希望将函数作为参数传递给另一个方法使用. 比如装饰器实际就是函数调用函数 举个例子,我想传递在调用方法之前打印一下时间: 使用函数当做入参 那就可以把方法名A当做入参传递 ...
- jquery+jquery.pagination+php+ajax 无刷新分页
<!DOCTYPE html> <html ><head><meta http-equiv="Content-Type" content= ...
- CSS3 box-shadow实现纸张的曲线投影效果
一般的投影效果,尤其通过CSS实现的投影效果(无论是CSS3,还是IE滤镜),都是直来直往的.纸张是有卷角的,其投影就是曲面的,如何使用CSS模拟出纸张的卷边曲线投影效果. <div class ...
- 彻底弄懂tf.Variable、tf.get_variable、tf.variable_scope以及tf.name_scope异同
https://blog.csdn.net/qq_22522663/article/details/78729029 1. tf.Variable与tf.get_variabletensorflow提 ...
- 98. Validate Binary Search Tree (Tree; DFS)
Given a binary tree, determine if it is a valid binary search tree (BST). Assume a BST is defined as ...
- 58. Length of Last Word (String)
Given a string s consists of upper/lower-case alphabets and empty space characters ' ', return the l ...
- http://218.245.4.98:20000/phpmyadmin:2018SCTF--easiest web - phpmyadmin
SCTF的web最简单题,好难好难好难. 直接进去就是PHPmyadmin界面(即mysql的网页界面),需要登录密码,这个我当时没有破解出来,谁知道账号密码是root/root咩,要是 ...