Orderd是spring core中定義的一個接口,使用它以及相關的Comparator和@Order註解,能夠實現對元素的排序。java
直接先說下@Order註解吧,使用場景較多。spring
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD}) @Documented public @interface Order { /** * The order value. * <p>Default is {@link Ordered#LOWEST_PRECEDENCE}. * @see Ordered#getOrder() */ int value() default Ordered.LOWEST_PRECEDENCE; }
Type,Method,Field均可以被註解;segmentfault
通常來講,屬性被註解順序是爲了序列化的便利,類被註解是功能或邏輯上的要求(好比攔截器的先後順序)ide
上面代碼中的Ordered.LOWEST_PRECEDENCE出如今Orderd接口定義中函數
public interface Ordered { /** * Useful constant for the highest precedence value. * @see java.lang.Integer#MIN_VALUE */ int HIGHEST_PRECEDENCE = Integer.MIN_VALUE; /** * Useful constant for the lowest precedence value. * @see java.lang.Integer#MAX_VALUE */ int LOWEST_PRECEDENCE = Integer.MAX_VALUE; /** * Get the order value of this object. * <p>Higher values are interpreted as lower priority. As a consequence, * the object with the lowest value has the highest priority (somewhat * analogous to Servlet {@code load-on-startup} values). * <p>Same order values will result in arbitrary sort positions for the * affected objects. * @return the order value * @see #HIGHEST_PRECEDENCE * @see #LOWEST_PRECEDENCE */ int getOrder(); }
能夠看到,低優先級是Integer的最大值,也就是說,數值越大,優先級越低(數值能夠爲負),能夠理解爲順序(第一個被服務的優先級高,取第一個的一爲優先級數值)this
private static final class StubOrdered implements Ordered { private final int order; public StubOrdered(int order) { this.order = order; } @Override public int getOrder() { return this.order; } } 做者:興浩 連接:https://www.jianshu.com/p/8442d21222ef 來源:簡書 簡書著做權歸做者全部,任何形式的轉載都請聯繫做者得到受權並註明出處。
後面看下Comparator的源碼就知道:lua
boolean p1 = (o1 instanceof PriorityOrdered); boolean p2 = (o2 instanceof PriorityOrdered); if (p1 && !p2) { return -1; } else if (p2 && !p1) { return 1; }
// Direct evaluation instead of Integer.compareTo to avoid unnecessary object creation. int i1 = getOrder(o1, sourceProvider); int i2 = getOrder(o2, sourceProvider); return (i1 < i2) ? -1 : (i1 > i2) ? 1 : 0;
spring提供了OrderUtils來獲取Class的Order信息.net
public class OrderUtilsTests { @Test public void getSimpleOrder() { assertEquals(Integer.valueOf(50), OrderUtils.getOrder(SimpleOrder.class, null)); } @Test public void getPriorityOrder() { assertEquals(Integer.valueOf(55), OrderUtils.getOrder(SimplePriority.class, null)); } @Order(50) private static class SimpleOrder {} @Priority(55) private static class SimplePriority {} } 做者:興浩 連接:https://www.jianshu.com/p/8442d21222ef 來源:簡書 簡書著做權歸做者全部,任何形式的轉載都請聯繫做者得到受權並註明出處。
@Priority的優先級會相比於Order高一些,其餘沒有區別,後面Comparator有影響。code
比較兩個對象的排列順序對象
private final OrderComparator comparator = new OrderComparator(); @Test public void compareOrderedInstancesBefore() { assertEquals(-1, this.comparator.compare( new StubOrdered(100), new StubOrdered(2000))); } @Test public void compareOrderedInstancesSame() { assertEquals(0, this.comparator.compare( new StubOrdered(100), new StubOrdered(100))); } @Test public void compareOrderedInstancesAfter() { assertEquals(1, this.comparator.compare( new StubOrdered(982300), new StubOrdered(100))); } private static final class StubOrdered implements Ordered { private final int order; public StubOrdered(int order) { this.order = order; } @Override public int getOrder() { return this.order; } } 做者:興浩 連接:https://www.jianshu.com/p/8442d21222ef 來源:簡書 簡書著做權歸做者全部,任何形式的轉載都請聯繫做者得到受權並註明出處。
AnnotationAwareOrderComparator繼承自OrderComparator
其能夠同時處理對象實現Ordered接口或@Order註解
其提供了靜態方法sort,能夠對List進行排序
@Test public void sortInstances() { List<Object> list = new ArrayList<>(); list.add(new B()); list.add(new A()); AnnotationAwareOrderComparator.sort(list); assertTrue(list.get(0) instanceof A); assertTrue(list.get(1) instanceof B); } @Order(1) private static class A { } @Order(2) private static class B { } 做者:興浩 連接:https://www.jianshu.com/p/8442d21222ef 來源:簡書 簡書著做權歸做者全部,任何形式的轉載都請聯繫做者得到受權並註明出處。
Demo2Config的對象將會先於Demo1Config初始化註冊
注意點:其構造函數的初始化並不生效
@Configuration @Order(2) public class Demo1Config { public Demo1Config() { System.out.println("Demo1Config"); } @Bean public Demo1Service demo1Service(){ System.out.println("demo1config 加載了"); return new Demo1Service(); } } @Configuration @Order(1) public class Demo2Config { public Demo2Config() { System.out.println("Demo2Config"); } @Bean public Demo2Service demo2Service(){ System.out.println("demo2config 加載了"); return new Demo2Service(); } } public class Main { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext("core.annotation.order2"); } } 輸出的結果信息: Demo1Config Demo2Config demo2config 加載了 demo1config 加載了 做者:興浩 連接:https://www.jianshu.com/p/8442d21222ef 來源:簡書 簡書著做權歸做者全部,任何形式的轉載都請聯繫做者得到受權並註明出處。