Spring核心接口之Ordered

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

喜欢就关注我
图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/453396.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

将本地代码上传至github

注册github账号 https://github.com/ 安装git工具 https://git-for-windows.github.io 1.在github中创建一个项目 2.填写相应信息&#xff0c;点击create Repository name: 仓库名称 Description(可选): 仓库描述介绍 Public, Private : 仓库权限&#xff08;公开共享&#xff…

禅道 php api,云禅道有API的方式可以获取数据吗

api相关手册&#xff1a;api接口查看&#xff0c;可以本地搭建和云禅道相同版本的禅道&#xff0c;然后admin 后台 二次开发 api&#xff0c;可以查看接口列表。api调用步骤PATH_INFO方式1、访问 http://x.com/api-getsessionid.json获取禅道session信息2、使用上一步获取的ses…

链表的头结点和尾节点的用处

某些情况下设置尾指针的好处 尾指针是指向终端结点的指针&#xff0c;用它来表示单循环链表可以使得查找链表的开始结点和终端结点都很方便&#xff0c;设一带头结点的单循环链表&#xff0c;其尾指针为rear&#xff0c;则开始结点和终端结点的位置分别是rear->next->ne…

经验从哪里来?从痛苦中来!

1 刚才发博客&#xff0c;写的几百字丢失&#xff0c;让我知道下次一定要在记事本里写好&#xff0c;再复制过来&#xff0c;避免丢失了 2 程序忘记备份&#xff0c;辛苦一个多月的东西没有了&#xff0c;只能找到1月前的版本&#xff0c;让我知道了&#xff0c;重要的东西必须…

oracle 加全文索引,Oracle创建全文索引

1、创建表空间&#xff0c;有必要将物理文件设置大一些2、创建基于这个表空间的用户3、创建需要建立全文索引的表4、用管理员帐户为使用这用户开发ctx_ddl权限grant execute on ctx_ddl to useer;5、创建适合的lexer(解析器)exec ctx_ddl.create_references(my_lexer,basic_le…

机器视觉系统需要考虑的十个问题

为了使用户在选择一款机器视觉系统时应该考虑的关键的、基本的特性方面提供指导。下面是选择一款机器视觉系统时要优先考虑的十个方面&#xff1a; 1. 定位器 对象或特征的精确定位是一个检测系统或由视觉引导的运动系统的重要功能。传统的物体定位采用的是灰度值校正来识别物体…

严蔚敏数据结构:链表实现一元多项式相加

一、基本概念 1、多项式pn(x)可表示成: pn(x)a0a1xa2x2…anxn。 listP{&#xff08;a0&#xff0c;e0&#xff09;&#xff0c;(a1&#xff0c;e1)&#xff0c;(a2&#xff0c;e2)&#xff0c;…&#xff0c;(an&#xff0c;en) }。在这种线性表描述中&#xff0c;各个结点…

Java二十三设计模式之------工厂方法模式

一、工厂方法模式&#xff08;Factory Method&#xff09; 工厂方法模式有三种 1、普通工厂模式&#xff1a;就是建立一个工厂类&#xff0c;对实现了同一接口的一些类进行实例的创建。首先看下关系图&#xff1a; 举例如下&#xff1a;&#xff08;我们举一个发送邮件和短信的…

无法转化为项目财富的技术或功能就是垃圾

技术人员可能有个习惯&#xff0c;也可以叫通病&#xff0c;发现一个新技术&#xff0c;或者新的想法&#xff0c;会把某个现有的东西做的更好&#xff0c;或者可以增加某个功能让系统看上去更完美。 如果这是一个产品&#xff0c;那么大家都会鼓励你去做&#xff0c;如果我们…

ibatis oracle function,IBATIS调用oracle function(函数)的步骤实例

IBATIS调用oracle function(函数)的方法实例引用create or replace function getClassifiedCode(p_planCode in varchar2 -- 险种代码,p_usageAttributeCode in varchar2 -- 使用性质代码,p_ownershipAttributeCode in varchar2 -- 所属性质代码,p_vehicleTypeCode in varchar2…

一元多项式乘法算法

我认为大致算法应该是这样的: 首先准备一个空的链表L。利用第一个多项式的的指针所指的节点数值乘以多项式二的每一项&#xff0c;将结果保存在链表L中。 然后将指向该节点的指针后移到下一个节点继续进行乘法运算&#xff0c;将所得结果加到L中&#xff08;这个操作已经在一…

堆以及stl堆的使用

概念 性质: 1.堆是一颗完全二叉树&#xff0c;用数组实现。    2.堆中存储数据的数据是局部有序的。 最大堆&#xff1a;1.任意一个结点存储的值都大于或等于其任意一个子结点中存储的值。      2.根结点存储着该树所有结点中的最大值。 最小堆&#xff1a;1.任意一个结…

读【36岁IT老人再次随笔】的读后感,你会哪些计算机语言?

论坛首页一篇&#xff1a;社区“揭穿最大谎言”事件 &#xff0c; 我看了&#xff0c;也顺便看了里面另一位仁兄的【36岁IT老人再次随笔】 其中关键的地方就是一个例子&#xff1a;你会哪些计算机语言&#xff1f; 这个问题很有意思&#xff0c;确实如网友回复里说到的&#xf…

php接收vue请求数据axios,详解vue axios用post提交的数据格式

Content-type的几种常见类型一、是什么&#xff1f;是Http的实体首部字段&#xff0c;用于说明请求或返回的消息主体是用何种方式编码&#xff0c;在request header和response header里都存在。二、几个常用类型&#xff1a;1、application/x-www-form-urlencoded这应该是最常见…

数据结构中的逻辑结构简介

数据的逻辑结构是对数据之间关系的描述&#xff0c;有时就把逻辑结构简称为数据结构。逻辑结构形式地定义为&#xff08;K&#xff0c;R&#xff09;&#xff08;或&#xff08;D&#xff0c;S&#xff09;&#xff09;&#xff0c;其中&#xff0c;K是数据元素的有限集&#x…

applicationContext配置文件模板1

<?xml version"1.0" encoding"utf-8"?> <beans      --整个配置文件的根节点&#xff0c;包含一个或多个bean元素 xmlns    --最基本的命名空间定义 xmlns:xsi  --最基本的命名空间定义 xmlns:context  --启动自动扫描或注解装配…

时间复杂度的一些计算规则

一些规则(引自&#xff1a;时间复杂度计算 ) 1) 加法规则 T(n,m) T1(n) T2(n) O (max ( f(n),g(m) ) 2) 乘法规则 T(n,m) T1(n) * T2(m) O (f(n) * g(m)) 3) 一个特例&#xff08;问题规模为常量的时间复杂度&#xff09; 在大O表示法里面有一个特例&#xff0c;如…

职场新人面试误区:我的技术好,所以你必须要请我?

这个是论坛的一个帖子。 前几天有家软件公司联系到我&#xff0c;去之前电话里跟他们的项目经理聊了两句&#xff0c;什么都明白了就没去面试 是老板先给我打的电话&#xff0c;问我做J2EE多久了&#xff0c;期望薪水什么个范围。。。 然后老板说&#xff0c;你稍等&#xff…

Oracle 基础

为什么80%的码农都做不了架构师&#xff1f;>>> Oracle DB笔录&#xff0c;以后会不断Add&#xff0c;欢迎留言补充! --cmd.exe(你懂得!) --[1]多个数据库实例&#xff0c;切换选择DB后&#xff0c;登录操作 set ORACLE_SIDorcl --选择DB orcl(你的DB实例名) --可在…

Linux执行命令提示Password,linux expect远程自动登录以及执行命令

linux远程自动登录以及执行命令远程登录该自动登录的过程是通过shell里面expect实现的&#xff0c;类似相当于开了一个类似于cmd的命令段输出IP和密码。注意该脚本能够执行的前提是安装了expectyum install -y expect直接上脚本&#xff1a;#!/usr/bin/expect …