博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring核心接口之Ordered
阅读量:6718 次
发布时间:2019-06-25

本文共 7818 字,大约阅读时间需要 26 分钟。

一、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. * 

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). *

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 {/** * 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. * 

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. *

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. *

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的优先级高于o12. 若对象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
handlerMappings; //HandlerAdapter集合 private List
handlerAdapters;

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

//detectAllHandlerMappings默认为true    if (this.detectAllHandlerMappings) {        // Find all HandlerMappings in the ApplicationContext, including ancestor contexts.        Map
matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false); if (!matchingBeans.isEmpty()) { this.handlerMappings = new ArrayList
(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_VALUEpublic abstract class AbstractHandlerMapping extends WebApplicationObjectSupport    implements HandlerMapping, Ordered {    private int order = Integer.MAX_VALUE;     AbstractHandlerMapping是RequestMappingHandlerMapping的父类。RequestMappingHandlerAdapterpublic abstract class AbstractHandlerMethodAdapter extends WebContentGenerator implements HandlerAdapter, Ordered {    // Ordered.LOWEST_PRECEDENCE只为Integer.MAX_VALUE    private int order = Ordered.LOWEST_PRECEDENCE;AbstractHandlerMethodAdapter是RequestMappingHandlerAdapter的父类。    可以看到RequestMappingHandlerMapping和RequestMappingHandlerAdapter没有设置order属性的时候,order属性的默认值都是Integer.MAX_VALUE,即优先级最低。 总结:    如果配置了
,又配置了自定义的RequestMappingHandlerAdapter,并且没有设置RequestMappingHandlerAdapter的order值,那么这2个RequestMappingHandlerAdapter的order值都是Integer.MAX_VALUE。那么谁先定义的,谁优先级高。
配置在自定义的RequestMappingHandlerAdapter配置之前,那么
配置的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
prams);}

2、实现接口

import java.util.Map;@Componentpublic 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
prams) { System.out.println("打印日志"); }}import java.util.Map;@Componentpublic 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
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
filters = context.getBeansOfType(Filter.class); System.out.println(filters.size()); List
f= new ArrayList
(filters.values()); OrderComparator.sort(f); for(int i=0; i
params = new HashMap
(); f.get(i).doFiler(params); }}

4、配置文件

喜欢就关注我

图片描述

转载地址:http://mpumo.baihongyu.com/

你可能感兴趣的文章
springMVC---配置文件解析(web.xml)
查看>>
angular4微信公众号开发遇到的问题
查看>>
React写个GitHub项目管理面板
查看>>
Redis 集群分片&分布式锁的使用
查看>>
String类型
查看>>
一致性 Hash 算法的实际应用
查看>>
个推微服务网关架构实践
查看>>
自定义标签的编码
查看>>
用一张图总结web缓存策略
查看>>
re模块与正则表达式
查看>>
第十天-《企业应用架构模式》-数据源架构模式
查看>>
如何快速学习Java?
查看>>
element-ui上传下载excel(超详细der)
查看>>
Python 进阶之路 (七) 隐藏的神奇宝藏:探秘Collections
查看>>
Webpack4 高手之路 第一天
查看>>
前端npm 安装包,精选大全集合
查看>>
Javascript实现冒泡排序与快速排序以及对快速排序的性能优化
查看>>
web认证机制
查看>>
Java多线程-Callable和Future
查看>>
MP3转换AAC格式哪个音频转换器好
查看>>