【技術累積】【點】【java】【25】Orderd

基礎概念

Orderd是spring core中定義的一個接口,使用它以及相關的Comparator和@Order註解,能夠實現對元素的排序。java

@Order

直接先說下@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

Orderd接口

上面代碼中的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

Order的兩種設置方法

  • 註解@Order(30)
  • 實現Orderd接口
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

  • 一個是Priority的有判斷,會先去比較;
boolean p1 = (o1 instanceof PriorityOrdered);
        boolean p2 = (o2 instanceof PriorityOrdered);
        if (p1 && !p2) {
            return -1;
        }
        else if (p2 && !p1) {
            return 1;
        }
  • 另外一個是實現接口後,若是沒有指定sourceProvider,會調用getOrder方法去比較數值
// 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;

OrderUtils

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

OrderComparator

比較兩個對象的排列順序對象

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

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
來源:簡書
簡書著做權歸做者全部,任何形式的轉載都請聯繫做者得到受權並註明出處。

Bean註冊順序

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
來源:簡書
簡書著做權歸做者全部,任何形式的轉載都請聯繫做者得到受權並註明出處。

參考文章

相關文章
相關標籤/搜索