java的ordered,Spring核心接口之Ordered

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

一、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的优先级高于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配置文件中添加:,那么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类

再看下配置的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 WebApplicationObjectSupport

implements 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_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优先级高。

如果配置了,又配置了自定义的RequestMappingHandlerMapping,并且没有设置RequestMappingHandlerMapping的order值。那么配置的RequestMappingHandlerMapping优先级高,因为内部会设置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;

@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 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 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

Map params = new HashMap();

f.get(i).doFiler(params);

}

}

4、配置文件

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”>

喜欢就关注我

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/207030.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月19日 下午2:36
下一篇 2026年3月19日 下午2:36


相关推荐

  • 控制指定的页面刷新

    控制指定的页面刷新当我们在某个页面进行操作之后 我们希望指定的那个页面能刷新 以小程序为例子我们需要设置一个全局的变量 作为刷新的列表 存储指定刷新的页面的路由 然后定义两个全局的函数 setReflash 和 execReflash setReflash 将当前页面的上一頁的路由或者指定的多个路由添加到刷新列表中 设置返回上一页要刷新提示 callbackfunc 要回调执行的函数

    2025年7月25日
    8
  • 基于逻辑回归的评分卡模型简单概述

    基于逻辑回归的评分卡模型简单概述评分卡模型 1 概述信用评分本质上是模式识别中的一类分类问题 将企业或者个体消费者划分为能够按期还本付息 即 好 客户 和违约 即 坏 两类 具体做法是根据历史数据中的样本 从已知的数据中找出违约及不违约客户的特征 从而总结出分类的规则 建立数学模型 用于测量价款人的违约风险 或者违约概率 为消费信贷决策提供依据 2 建模的准备 2 1 目标变量的准备研究的目标变量为客户是否具有违约行

    2026年3月19日
    1
  • telnet远程登录AAA认证

    telnet远程登录AAA认证R1<Huawei>system-view//进入全局配置模式[Huawei]sysnameR1//改名[R1]undoinfo-centerenable//关闭信息告警提示[R1]interfaceg0/0/0//进入g/0/0接口[R1-GigabitEthernet0/0/0]ipaddress192.168.100…

    2022年6月7日
    39
  • python期货程序化开发_使用文华财经进行期货程序化真的很low,自己编程才是正途…「建议收藏」

    python期货程序化开发_使用文华财经进行期货程序化真的很low,自己编程才是正途…「建议收藏」一、目前期货程序化现状由于有免费的CTP接口,期货程序化交易目前比较普遍,很多人都尝试过在文华财经、金字塔之类的软件上回测和编写实盘策略。期货程序化交易有很多优点:程序会按照设计自动执行,不受任何其它因素干扰,设计正确的请假下不会出错。借助于程序,交易速度更快,远远超过人工下单的速度。节省人工成本,一个策略可以部署多个机器人,特别当前期货存在夜盘的情况下,耗费非常大的人力成本。可以说,从事期货交易…

    2022年10月8日
    5
  • pytest的使用_子程序调用次数不管用

    pytest的使用_子程序调用次数不管用Pytest执行用例规则Pytest在命令行中支持多种方式来运行和选择测试用例1.对某个目录下所有的用例pytest2.对模块中进行测试pytesttest_mod.py3.对文件夹进行

    2022年7月28日
    9
  • 【自动控制原理】拉氏变换

    【自动控制原理】拉氏变换本文主要介绍了拉氏变换的性质与意义 给出了几个常用拉氏变换

    2026年3月19日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号