Spring之Ordered

SpringMVC之HandlerMapping中,AbstractHandlerMapping實現(xiàn)了Ordered接口,那么Ordered接口的作用是什么呢?接下來,我們看一下Ordered接口。

Ordered接口

接口定義

public interface Ordered {
    int HIGHEST_PRECEDENCE = Integer.MIN_VALUE;
    int LOWEST_PRECEDENCE = Integer.MAX_VALUE;
    int getOrder();
}

//OrderComparator類compare()
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;
  }

  int i1 = getOrder(o1);
  int i2 = getOrder(o2);
  return (i1 < i2) ? -1 : (i1 > i2) ? 1 : 0;  
}

上面代碼的邏輯: OrderComparator比較器進行排序的時候,若2個對象中有一個對象實現(xiàn)了PriorityOrdered接口,那么這個對象的優(yōu)先級更高;若2個對象都是PriorityOrdered或Ordered接口的實現(xiàn)類,那么比較Ordered接口的getOrder方法得到order值,值越低,優(yōu)先級越高。

SpringMVC中Ordered接口例子

修改dispatcher-servlet.xml文件

<!-- 自定義RequestMappingHandlerAdapter-->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
    <!-- 自定義參數(shù)解析器 -->
    <property name="customArgumentResolvers">
        <list>
            <bean class="com.qding.base.resolver.ArgumentFromJsonResolver" />
        </list>
    </property>
</bean>

<!-- 自定義RequestMappingHandlerMapping -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
  <property name="interceptors">
    <bean class="interceptor.DefaultInterceptor"/>
  </property> 
  <!-- order設(shè)置為-1  -->
  <!-- <property name="order" value="-1"/> -->
</bean>

<mvc:annotation-driven />

當(dāng)添加了<mvc:annotation-driven />這段代碼,那么SpringMVC默認會注入RequestMappingHandlerAdapter和RequestMappingHandlerMapping這兩個類。這時項目就會有兩個RequestMappingHandlerMapping,那么這個兩個RequestMappingHandlerMapping那個優(yōu)先級高呢?

initHandlerMappings()源碼

//DispatcherServlet類中initHandlerMappings()實現(xiàn)
private void initHandlerMappings(ApplicationContext context) {
        this.handlerMappings = null;

        if (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.
                OrderComparator.sort(this.handlerMappings);
            }
        }
        else {
            try {
                HandlerMapping hm = context.getBean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class);
                this.handlerMappings = Collections.singletonList(hm);
            }
            catch (NoSuchBeanDefinitionException ex) {
                // Ignore, we'll add a default HandlerMapping later.
            }
        }

        // Ensure we have at least one HandlerMapping, by registering
        // a default HandlerMapping if no other mappings are found.
        if (this.handlerMappings == null) {
            this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class);
            if (logger.isDebugEnabled()) {
                logger.debug("No HandlerMappings found in servlet '" + getServletName() + "': using default");
            }
        }
    }

//OrderComparator類中實現(xiàn)排序的方法
public static void sort(List<?> list) {
        if (list.size() > 1) {
            Collections.sort(list, INSTANCE);
        }
    }

@Override
    public int compare(Object o1, Object o2) {
        return doCompare(o1, o2, null);
    }

    private int doCompare(Object o1, Object o2, OrderSourceProvider sourceProvider) {
        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, sourceProvider);
        int i2 = getOrder(o2, sourceProvider);
        return (i1 < i2) ? -1 : (i1 > i2) ? 1 : 0;
    }

通過上面的代碼走讀得出:如果配置了<mvc:annotation-driven />,又配置了自定義的RequestMappingHandlerMapping,并且沒有設(shè)置自定義RequestMappingHandlerMapping的order值。那么<mvc:annotation-driven />配置的RequestMappingHandlerMapping優(yōu)先級高,因為<mvc:annotation-driven />內(nèi)部會設(shè)置RequestMappingHandlerMapping的order為0。我們可以將自定義的RequestMappingHandlerMapping的order設(shè)置為-1提高它的優(yōu)先級。

備注:
自定義的RequestMappingHandlerAdapter和<mvc:annotation-driven />的優(yōu)先級?自定義AdapterRequestMappingHandlerAdapter沒有設(shè)置order的值情況下,* 誰先定義誰的優(yōu)先級高*。具體我們可以走讀initHandlerAdapters(context)。

作者:忘凈空
鏈接:http://www.itdecent.cn/p/d87e5de747a5
來源:簡書
簡書著作權(quán)歸作者所有,任何形式的轉(zhuǎn)載都請聯(lián)系作者獲得授權(quán)并注明出處。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容