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.pswp.cn/news/453396.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/453396.shtml
英文地址,請注明出處:http://en.pswp.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 …