一、Ordered接口介绍
Spring中提供了一个Ordered接口。从单词意思就知道Ordered接口的作用就是用来排序的。
Spring框架是一个大量使用策略设计模式的框架,这意味着有很多相同接口的实现类,那么必定会有优先级的问题。于是Spring就提供了Ordered这个接口,来处理相同接口实现类的优先级问题。

二、Ordered接口分析
1、Ordered接口的定义:

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();

}

该接口卡只有1个方法getOrder()及 2个变量HIGHEST_PRECEDENCE最高级(数值最小)和LOWEST_PRECEDENCE最低级(数值最大)。

2、OrderComparator类:实现了Comparator接口的一个比较器。

public class OrderComparator implements Comparator<Object> {
/*** Shared default instance of OrderComparator.*/
public static final OrderComparator INSTANCE = new OrderComparator();public int compare(Object o1, Object o2) {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);int i2 = getOrder(o2);return (i1 < i2) ? -1 : (i1 > i2) ? 1 : 0;
}/*** Determine the order value for the given object.* <p>The default implementation checks against the {@link Ordered}* interface. Can be overridden in subclasses.* @param obj the object to check* @return the order value, or {@code Ordered.LOWEST_PRECEDENCE} as fallback*/
protected int getOrder(Object obj) {return (obj instanceof Ordered ? ((Ordered) obj).getOrder() : Ordered.LOWEST_PRECEDENCE);
}/*** Sort the given List with a default OrderComparator.* <p>Optimized to skip sorting for lists with size 0 or 1,* in order to avoid unnecessary array extraction.* @param list the List to sort* @see java.util.Collections#sort(java.util.List, java.util.Comparator)*/
public static void sort(List<?> list) {if (list.size() > 1) {Collections.sort(list, INSTANCE);}
}/*** Sort the given array with a default OrderComparator.* <p>Optimized to skip sorting for lists with size 0 or 1,* in order to avoid unnecessary array extraction.* @param array the array to sort* @see java.util.Arrays#sort(Object[], java.util.Comparator)*/
public static void sort(Object[] array) {if (array.length > 1) {Arrays.sort(array, INSTANCE);}
}

}

提供了2个静态排序方法:sort(List<?> list)用来排序list集合、sort(Object[] array)用来排序Object数组
可以下OrderComparator类的public int compare(Object o1, Object o2)方法,可以看到另外一个类PriorityOrdered,这个方法的逻辑解析如下:

1. 若对象o1是Ordered接口类型,o2是PriorityOrdered接口类型,那么o2的优先级高于o1
2. 若对象o1是PriorityOrdered接口类型,o2是Ordered接口类型,那么o1的优先级高于o2     3.其他情况,若两者都是Ordered接口类型或两者都是PriorityOrdered接口类型,调用Ordered接口的getOrder方法得到order值,order值越大,优先级越小

简单来说就是:
OrderComparator比较器进行排序的时候,若2个对象中有一个对象实现了PriorityOrdered接口,那么这个对象的优先级更高。若2个对象都是PriorityOrdered或Ordered接口的实现类,那么比较Ordered接口的getOrder方法得到order值,值越低,优先级越高。

三、Spring中使用Ordered接口在的例子
在spring配置文件中添加:<mvc:annotation-driven/>,那么SpringMVC默认会注入RequestMappingHandlerAdapter和RequestMappingHandlerMapping这两个类。 既然SpringMVC已经默认为我们注入了RequestMappingHandlerAdapter和RequestMappingHandlerMapping这两个类,如果再次配置这两个类,将会出现什么效果呢?
当我们配置了annotation-driven以及这两个bean的时候。Spring容器就有了2个RequestMappingHandlerAdapter和2个RequestMappingHandlerMapping。
DispatcherServlet内部有HandlerMapping(RequestMappingHandlerMapping是其实现类)集合和HandlerAdapter(RequestMappingHandlerAdapter是其实现类)集合。

    //RequestMappingHandlerMapping集合private List<HandlerMapping> handlerMappings;//HandlerAdapter集合private List<HandlerAdapter> handlerAdapters;

在仔细看下DispatcherServlet类的private void initHandlerMappings(ApplicationContext context)方法可以看到如下代码:

    //detectAllHandlerMappings默认为trueif (this.detectAllHandlerMappings) {// Find all HandlerMappings in the ApplicationContext, including ancestor contexts.Map<String, HandlerMapping> matchingBeans =BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);if (!matchingBeans.isEmpty()) {this.handlerMappings = new ArrayList<HandlerMapping>(matchingBeans.values());// We keep HandlerMappings in sorted order.//进行排序AnnotationAwareOrderComparator.sort(this.handlerMappings);}}
AnnotationAwareOrderComparator继承了OrderComparator类

再看下<mvc:annotation-driven/>配置的RequestMappingHandlerMapping和RequestMappingHandlerAdapter
@Bean
public RequestMappingHandlerAdapter requestMappingHandlerAdapter()方法
@Bean
public RequestMappingHandlerMapping requestMappingHandlerMapping()方法 分析代码可以知道:RequestMappingHandlerMapping默认会设置order属性为0,RequestMappingHandlerAdapter没有设置order属性。

进入RequestMappingHandlerMapping和RequestMappingHandlerAdapter代码里面看看它们的order属性是如何定义的。

RequestMappingHandlerMapping
// Ordered.LOWEST_PRECEDENCE只为Integer.MAX_VALUE
public abstract class AbstractHandlerMapping extends WebApplicationObjectSupportimplements HandlerMapping, Ordered {private int order = Integer.MAX_VALUE; AbstractHandlerMapping是RequestMappingHandlerMapping的父类。RequestMappingHandlerAdapter
public abstract class AbstractHandlerMethodAdapter extends WebContentGenerator implements HandlerAdapter, Ordered {// Ordered.LOWEST_PRECEDENCE只为Integer.MAX_VALUEprivate int order = Ordered.LOWEST_PRECEDENCE;AbstractHandlerMethodAdapter是RequestMappingHandlerAdapter的父类。    可以看到RequestMappingHandlerMapping和RequestMappingHandlerAdapter没有设置order属性的时候,order属性的默认值都是Integer.MAX_VALUE,即优先级最低。
总结:    如果配置了<mvc:annotation-driven/>,又配置了自定义的RequestMappingHandlerAdapter,并且没有设置RequestMappingHandlerAdapter的order值,那么这2个RequestMappingHandlerAdapter的order值都是Integer.MAX_VALUE。那么谁先定义的,谁优先级高。 <mvc:annotation-driven/>配置在自定义的RequestMappingHandlerAdapter配置之前,那么<mvc:annotation-driven/>配置的RequestMappingHandlerAdapter优先级高,反之自定义的RequestMappingHandlerAdapter优先级高。

如果配置了<mvc:annotation-driven/>,又配置了自定义的RequestMappingHandlerMapping,并且没有设置RequestMappingHandlerMapping的order值。那么<mvc:annotation-driven/>配置的RequestMappingHandlerMapping优先级高,因为<mvc:annotation-driven />内部会设置RequestMappingHandlerMapping的order为0。

四、应用
1、定义接口

import java.util.Map;
import org.springframework.core.Ordered;public interface Filter extends Ordered{public void doFiler(Map<String, String> prams);}

2、实现接口

import java.util.Map;
@Component
public class LogFilter implements Filter {private int order =1;public int getOrder() {return order;}public void setOrder(int order) {this.order = order;}public void doFiler(Map<String, String> prams) {System.out.println("打印日志");}
}import java.util.Map;
@Component
public class PowerLogFilter implements Filter {private int order =2;public int getOrder() {return order;}public void setOrder(int order) {this.order = order;}public void doFiler(Map<String, String> prams) {System.out.println("权限控制");}
}

3、测试进行排序

public static void main(String[] args) throws Exception {
String config = Test.class.getPackage().getName().replace('.', '/') + "/bean.xml";ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(config);context.start();Map<String, Filter> filters = context.getBeansOfType(Filter.class);System.out.println(filters.size());List<Filter> f= new ArrayList<Filter>(filters.values());OrderComparator.sort(f);for(int i=0; i<f.size(); i++){Map<String, String> params = new HashMap<String, String>();f.get(i).doFiler(params);}
}

4、配置文件

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"><context:component-scan base-package="com" /></beans>

喜欢就关注我

Spring核心接口之Ordered相关推荐

  1. 一文带你了解Spring核心接口Ordered的实现及应用

    前言 最近在看框架的时候,发现了这个接口,在此进行总结,希望能够给大家帮助,同时提升自己. order接口的大体介绍 Spring框架中有这个一个接口,名字叫Ordered,联想我们在数据库中应用的O ...

  2. spring中基础核心接口总结

    spring中基础核心接口总结 理解这几个接口,及其实现类就可以快速了解spring,具体的用法参考其他spring资料 1.BeanFactory最基础最核心的接口 重要的实现类有: XmlBean ...

  3. Spring : Spring事物支持核心接口

    1.美图 2.核心接口概览 3.TransactionDefinition TransactionDefinition–>定义与spring兼容的事务属性的接口 public interface ...

  4. Spring AOP(二)AOPAlliance与SpringAOP核心接口介绍

    目录 AOP联盟 1. Advice.MethodInterceptor拦截器(invoke方法:调用invocation.proceed) 2.Joinpoint .MethodInvocation ...

  5. Spring核心知识

    Spring框架自2002年诞生以来一直备受开发者青睐,它包括SpringMVC.SpringBoot.Spring Cloud.Spring Cloud Dataflow等解决方案.有人亲切的称之为 ...

  6. 护网必备技能:Spring Boot 接口数据加解密 功能实现

    护网必备技能:Spring Boot 接口数据加解密 功能实现 文章目录 护网必备技能:Spring Boot 接口数据加解密 功能实现 1. 尽量少改动,不影响之前的业务逻辑: 2. 考虑到时间紧迫 ...

  7. Spring 核心方法 refresh 刷新流程简要概述及相关源码扩展实现(一)

    前言 Spring 启动流程解析 Refresh 内部方法全解析 prepareRefresh obtainFreshBeanFactory AbstractApplicationContext 类以 ...

  8. Spring 核心方法 refresh 刷新流程简要概述及相关源码扩展实现(二)

    前言 registerBeanPostProcessors initMessageSource 如何实际应用国际化处理 initApplicationEventMulticaster onRefres ...

  9. Spring核心——IOC处理器扩展

    为什么80%的码农都做不了架构师?>>>    非侵入式框架 Spring一直标注自己是一个非侵入式框架.非侵入式设计的概念并不新鲜,目标就是降低使用者和框架代码的耦合,毕竟框架的开 ...

最新文章

  1. [shell]简单的shell提示和参数脚本
  2. Replation requires the actual server name ... Replication.Utilies
  3. 通过完整示例来理解如何使用 epoll
  4. nyoj116士兵杀敌2
  5. [ ArcGIS for Server 10.1 系列 ] - 分布式部署GIS Servers
  6. 【Linux系统编程学习】信号、信号集以其相关函数
  7. ajax动态获取url参数值,获取URL参数的方法
  8. tensorflow学习笔记(1):sess.run()
  9. mac xampp连接mysql数据库_请问在mac下xampp无法读取mysql的数据
  10. java备忘录模式应用场景_Java描述设计模式(24):备忘录模式
  11. ES6新特性 - const let var
  12. startlogging中设置setstdout=false来禁用这个功能。_无线路由器的安全功能,你知道多少?...
  13. KDevelop下如何选择不同的源文件进行执行
  14. 第三部分数据结构[专业课考试3]
  15. 如何发布一个BT种子文件
  16. Fisher精确检验
  17. excel合并两列内容_excel新手问题:怎么把两列数据合并到一起?用这个公式
  18. 【Unity2D好项目分享】提高游戏人物打击感
  19. nexmo 验证码的使用
  20. Win7安装补丁KB2670838

热门文章

  1. Seaborn——绘制统计图形
  2. 帧同步和状态同步(一)
  3. linux下的RPC
  4. 小谈Online-game服务器端设计(1、2)
  5. 《游戏编程入门 4th》笔记(1 / 14):Windows初步
  6. 《Python Cookbook 3rd》笔记(2.9):将Unicode文本标准化
  7. linux+shell+func,Linux shell编程笔记总结
  8. FFmpeg示例程序合集-批量编译脚本
  9. 开发者应该了解的API技术清单!
  10. 经理人如何与这“六种人”打交道?