前言 最近在看框架的时候,发现了这个接口,在此进行总结,希望能够给大家帮助,同时提升自己。order接口的大体介绍 Spring框架中有这个一个接口,名字叫Ordered,联想我们在数据库中应用的Ordered,很容易想到它的含义就是用来排序。那么问题来了,Spring中为什么要定义这样一个排序接口呢。我们知道spring框架使用了大量的策略设计模式。策略设计模式意味着我们的同一个接口,会有大量的不同实现。那么这么多实现,先执行哪个,后执行哪个呢。这就产生了一个排序和优先级的问题,于是Ordered接口登场,用来解决这一问题。ordered接口的正式介绍 首先我们通过spring的源码看一下Ordered接口,源码如下:publicinterfaceOrdered{intHIGHESTPRECEDENCE2147483648;intLOWESTPRECEDENCE2147483647;intgetOrder();} 从上述代码中,我们可以看到ordered接口的实现是非常简单的。有一个最高的优先级和一个最低的优先级,还提供了一个获得当前实现类的order数值的方法。spring的order中。越小的值,优先级越高,越大的值优先级越低。ordered接口的应用 介绍完ordered接口之后,我们来看一下实际的应用场景。有一个典型的场景,我们知道spring的事务管理是通过aop切面来实现的。当我们自己写aop实现的时候,与事务的切面同时切到了一段代码。那么spring应该先执行谁呢。举一个具体的例子,我们写了一个切换数据源的aspect切面。如果说事务的执行在数据源切换的前面,那么切换数据源就失败了。我们肯定希望先执行切换数据源,再执行事务。于是ordered的应用场景就来了。假设我们写一个下面的切面。ComponentAspectpublicclassChangeDataBaseimplementsOrdered{拦截所有的service操作Pointcut(execution(com。color。。service。。(。。)))publicvoidpoint(){}Before(point())publicvoidonlyReadPre(){DataSourceContextHolder。setDataSourceType(DataSourceType。MYSQL);System。out。println(数据库切换MYSQL);}After(point())publicvoidonlyReadPast(){DataSourceContextHolder。setDataSourceType(DataSourceType。ORACLE);System。out。println(数据库切换回ORACLE);}OverridepublicintgetOrder(){return1;}} 在上述代码中,我们定义了一个切点,用于拦截所有的service的方法。然后再方法执行前,我们将数据库切换到mysql,方法执行之后,数据库切换成oracle。最后重写了ordered接口的getOrder方法。这里我们设置order的级别为1。这个时候,我们在配置事务切面的时候。在xml中配置order。tx:annotationdriventransactionmanagertransactionManagerorder2 如果是使用注入bean的方式的话,直接实现接口和上方一样使用即可。这个时候,我们就会发现。切换数据源的方法会永远在事务之前执行,这就实现了我们的目的。order注解的使用 读到现在的读者在想,还要实现接口感觉好麻烦啊,有没有什么更方便的方法呢。当然有,我们介绍一下Order注解。还是先看一下order注解的源码。Retention(RetentionPolicy。RUNTIME)Target({ElementType。TYPE,ElementType。METHOD,ElementType。FIELD})DocumentedpublicinterfaceOrder{intvalue()default2147483647;} 默认的优先级是最小的。我们在使用的时候,只要在类上面打上order注解即可。我们模拟两个类,打上order注解,然后再spring容器启动的时候,对类进行空参构造函数加载,通过空参构造函数里面的打印情况,我们就可以看到类初始化和执行的顺序。建立我们的第一个order类。Component使用order属性,设置该类在spring容器中的加载顺序Order(1)publicclassOrder1{privatefinalintORDERED1;publicOrder1(){System。out。println(this);}OverridepublicStringtoString(){returnOrder1isloadedORDEREDORDERED〕;}} 建立我们的第二个order类。Component使用order属性,设置该类在spring容器中的加载顺序Order(2)publicclassOrder2{privatefinalintORDERED2;publicOrder2(){System。out。println(this);}OverridepublicStringtoString(){returnOrder2isloadedORDEREDORDERED〕;}} 启动spring容器之后,我们看到控制台执行如下结果。Order1isloadedORDERED1〕Order2isloadedORDERED2〕orderComparator的介绍 那么我们假如想知道一个类的order的值,或者想比较两个类的order值谁大谁小,这个时候要如何操作呢,Spring贴心的给我们提供了一个类。OrderComparator,通过这个类,我们获得实例后,使用它所提供的getOrder或者compare方法即可实现上述的需求。我们照例还是先来看一下源码。publicclassOrderComparatorimplementsComparatorObject{publicstaticfinalOrderComparatorINSTANCEnewOrderComparator();publicOrderComparator(){}publicComparatorObjectwithSourceProvider(OrderComparator。OrderSourceProvidersourceProvider){return(o1,o2){returnthis。doCompare(o1,o2,sourceProvider);};}publicintcompare(NullableObjecto1,NullableObjecto2){returnthis。doCompare(o1,o2,(OrderComparator。OrderSourceProvider)null);}privateintdoCompare(NullableObjecto1,NullableObjecto2,NullableOrderComparator。OrderSourceProvidersourceProvider){booleanp1o1instanceofPriorityOrdered;booleanp2o2instanceofPriorityOrdered;if(p1!p2){return1;}elseif(p2!p1){return1;}else{inti1this。getOrder(o1,sourceProvider);inti2this。getOrder(o2,sourceProvider);returnInteger。compare(i1,i2);}}privateintgetOrder(NullableObjectobj,NullableOrderComparator。OrderSourceProvidersourceProvider){Integerordernull;if(obj!nullsourceProvider!null){ObjectorderSourcesourceProvider。getOrderSource(obj);if(orderSource!null){if(orderSource。getClass()。isArray()){Object〔〕sourcesObjectUtils。toObjectArray(orderSource);Object〔〕var6sources;intvar7sources。length;for(intvar80;var8var7;var8){Objectsourcevar6〔var8〕;orderthis。findOrder(source);if(order!null){break;}}}else{orderthis。findOrder(orderSource);}}}returnorder!null?order。intValue():this。getOrder(obj);}protectedintgetOrder(NullableObjectobj){if(obj!null){Integerorderthis。findOrder(obj);if(order!null){returnorder。intValue();}}return2147483647;}NullableprotectedIntegerfindOrder(Objectobj){returnobjinstanceofOrdered?((Ordered)obj)。getOrder():null;}NullablepublicIntegergetPriority(Objectobj){returnnull;}publicstaticvoidsort(Listlt;?list){if(list。size()1){list。sort(INSTANCE);}}publicstaticvoidsort(Object〔〕array){if(array。length1){Arrays。sort(array,INSTANCE);}}publicstaticvoidsortIfNecessary(Objectvalue){if(valueinstanceofObject〔〕){sort((Object〔〕)((Object〔〕)value));}elseif(valueinstanceofList){sort((List)value);}}FunctionalInterfacepublicinterfaceOrderSourceProvider{NullableObjectgetOrderSource(Objectvar1);}} 我们先来重点看一下doCompare方法。判断逻辑如下:若对象o1是Ordered接口类型,o2是PriorityOrdered接口类型,那么o2的优先级高于o1若对象o1是PriorityOrdered接口类型,o2是Ordered接口类型,那么o1的优先级高于o2其他情况,若两者都是Ordered接口类型或两者都是PriorityOrdered接口类型,调用Ordered接口的getOrder方法得到order值,order值越大,优先级越小那么一句话来说就是这样的。OrderComparator比较器进行排序的时候,若2个对象中有一个对象实现了PriorityOrdered接口,那么这个对象的优先级更高。若2个对象都是PriorityOrdered或Ordered接口的实现类,那么比较Ordered接口的getOrder方法得到order值,值越低,优先级越高。 再来看一下getOrder方法。传入一个对象后,通过provider取得原始对象。如果不为空,继续进行判断。如果是数组对象,对对象进行遍历,得到order后,跳出。如果不是数组则直接获得对象的order。最后如果order如果不是空,直接返回order的int值,为空的时候,通过findOrder查看,返回的是order的最大值,也就是最低优先级。protectedintgetOrder(NullableObjectobj){if(obj!null){Integerorderthis。findOrder(obj);if(order!null){returnorder。intValue();}}return2147483647;}总结 至此ordered相关的东西就介绍到此为止,文中难免有不足,希望大家提出指正,感谢。