在SpringMVC之HandlerMapping中,AbstractHandlerMapping實現了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個對象中有一個對象實現了PriorityOrdered接口,那么這個對象的優先級更高;若2個對象都是PriorityOrdered或Ordered接口的實現類,那么比較Ordered接口的getOrder方法得到order值,值越低,優先級越高。
SpringMVC中Ordered接口例子
修改dispatcher-servlet.xml文件
<!-- 自定義RequestMappingHandlerAdapter-->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<!-- 自定義參數解析器 -->
<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設置為-1 -->
<!-- <property name="order" value="-1"/> -->
</bean>
<mvc:annotation-driven />
當添加了<mvc:annotation-driven />這段代碼,那么SpringMVC默認會注入RequestMappingHandlerAdapter和RequestMappingHandlerMapping這兩個類。這時項目就會有兩個RequestMappingHandlerMapping,那么這個兩個RequestMappingHandlerMapping那個優先級高呢?
initHandlerMappings()源碼
//DispatcherServlet類中initHandlerMappings()實現
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類中實現排序的方法
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,并且沒有設置自定義RequestMappingHandlerMapping的order值。那么<mvc:annotation-driven />配置的RequestMappingHandlerMapping優先級高,因為<mvc:annotation-driven />內部會設置RequestMappingHandlerMapping的order為0。我們可以將自定義的RequestMappingHandlerMapping的order設置為-1提高它的優先級。
備注:
自定義的RequestMappingHandlerAdapter和<mvc:annotation-driven />的優先級?自定義AdapterRequestMappingHandlerAdapter沒有設置order的值情況下,* 誰先定義誰的優先級高*。具體我們可以走讀initHandlerAdapters(context)。