zoukankan      html  css  js  c++  java
  • 【技术累积】【点】【java】【25】Orderd

    基础概念

    Orderd是spring core中定义的一个接口,使用它以及相关的Comparator和@Order注解,可以实现对元素的排序。

    @Order

    直接先说下@Order注解吧,使用场景较多。

    @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都可以被注解;

    一般来说,属性被注解顺序是为了序列化的便利,类被注解是功能或逻辑上的要求(比如拦截器的前后顺序)

    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的最大值,也就是说,数值越大,优先级越低(数值可以为负),可以理解为顺序(第一个被服务的优先级高,取第一个的一为优先级数值)

    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的源码就知道:

    • 一个是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信息

    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有影响。

    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
    來源:简书
    简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
    

    参考文章

  • 相关阅读:
    MongoDB入门下
    MongoDB简介
    MongoDB 查询上
    MongoDB 创建,更新,删除文档 下
    MongoDB 创建,更新,删除文档 上
    SqlServer 对 数据类型 text 的操作
    Asp.Net编码
    MongoDB 查询下
    (基于Java)编写编译器和解释器第3A章:基于Antlr构造词法分析器(连载)
    (基于Java)编写编译器和解释器第2章:框架I:编译器和解释器第三部分(连载)
  • 原文地址:https://www.cnblogs.com/andy1202go/p/9870319.html
Copyright © 2011-2022 走看看