您的位置:首页 > 编程语言 > Java开发

集合类自定义排序和springMVC viewResolver的顺序问题

2017-10-25 10:10 351 查看
看了springMVC的dispatcherServlet的源码,有个地方不是特别明白,一路找资料,懂了 所以需要记录一下。

关于initViewResolvers方法,我们知道springMVC里有一个视图解析器的概念。同一个项目可能会需要配置多个视图解析器。对于具有REST风格的服务器更是如此。

通过对源码的查看,视图解析器在配置时,可以设置order属性,这个值关联到视图解析器的执行顺序。值越小优先级越高,可以为负数。具体原理,我会在下面详细说明。

首先我们可以看看initViewResolvers方法:

private void initViewResolvers(ApplicationContext context) {
this.viewResolvers = null;
if(this.detectAllViewResolvers) {
Map vr = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, ViewResolver.class, true, false);
if(!vr.isEmpty()) {
this.viewResolvers = new ArrayList(vr.values());
AnnotationAwareOrderComparator.sort(this.viewResolvers);
}
} else {
try {
ViewResolver vr1 = (ViewResolver)context.getBean("viewResolver", ViewResolver.class);
this.viewResolvers = Collections.singletonList(vr1);
} catch (NoSuchBeanDefinitionException var3) {
;
}
}

if(this.viewResolvers == null) {
this.viewResolvers = this.getDefaultStrategies(context, ViewResolver.class);
if(this.logger.isDebugEnabled()) {
this.logger.debug("No ViewResolvers found in servlet \'" + this.getServletName() + "\': using default");
}
}

}首先会取出 所有在ioc里注册过的viewResolver接口的实现(也就是配置的多个视图解析器),并将之放入数组中。
之后,利用AnnotationAwareOrderComparator类中sort方法进行排序,这个AnnotationAwareOrderComparator类继承了OrderComparator。而OrderComparator类通过我的研究,发现这个类在spring里运用很广泛。OrderComparator实现了Comparator接口。我们知道java集合类自定义排序正是需要实现Comparator接口。所以不难看出OrderComparator这个类是用于spring内bean排序。

public class OrderComparator implements Comparator<Object> {
public static final OrderComparator INSTANCE = new OrderComparator();

public OrderComparator() {
}

public Comparator<Object> withSourceProvider(final OrderComparator.OrderSourceProvider sourceProvider) {
return new Comparator() {
public int compare(Object o1, Object o2) {
return OrderComparator.this.doCompare(o1, o2, sourceProvider);
}
};
}

public int compare(Object o1, Object o2) {
return this.doCompare(o1, o2, (OrderComparator.OrderSourceProvider)null);
}

private int doCompare(Object o1, Object o2, OrderComparator.OrderSourceProvider sourceProvider) {
boolean p1 = o1 instanceof PriorityOrdered;
boolean p2 = o2 instanceof PriorityOrdered;
if(p1 && !p2) {
return -1;
} else if(p2 && !p1) {
return 1;
} else {
int i1 = this.getOrder(o1, sourceProvider);
int i2 = this.getOrder(o2, sourceProvider);
return i1 < i2?-1:(i1 > i2?1:0);
}
}

private int getOrder(Object obj, OrderComparator.OrderSourceProvider sourceProvider) {
Integer order = null;
if(sourceProvider != null) {
Object orderSource = sourceProvider.getOrderSource(obj);
if(orderSource != null && orderSource.getClass().isArray()) {
Object[] sources = ObjectUtils.toObjectArray(orderSource);
Object[] var6 = sources;
int var7 = sources.length;

for(int var8 = 0; var8 < var7; ++var8) {
Object source = var6[var8];
order = this.findOrder(source);
if(order != null) {
break;
}
}
} else {
order = this.findOrder(orderSource);
}
}

return order != null?order.intValue():this.getOrder(obj);
}

protected int getOrder(Object obj) {
Integer order = this.findOrder(obj);
return order != null?order.intValue():2147483647;
}

protected Integer findOrder(Object obj) {
return obj instanceof Ordered?Integer.valueOf(((Ordered)obj).getOrder()):null;
}

public Integer getPriority(Object obj) {
return null;
}

public static void sort(List<?> list) {
if(list.size() > 1) {
Collections.sort(list, INSTANCE);
}

}

public static void sort(Object[] array) {
if(array.length > 1) {
Arrays.sort(array, INSTANCE);
}

}

public static void sortIfNecessary(Object value) {
if(value instanceof Object[]) {
sort((Object[])((Object[])value));
} else if(value instanceof List) {
sort((List)value);
}

}

public interface OrderSourceProvider {
Object getOrderSource(Object var1);
}
}

它实现了compare方法,并通过findOrder方法,得到viewResolver的order属性(在配置文件里设置的order值),这里的order在spring.core包里是一个接口类,规定了order的最大值与最小值,各个viewResolver的实现类(也可以是其他bean)各自实现自己的getOrder方法。通过查看viewResolver的一些实现类,我发现若bean实现了order接口且配置bean时没设置order值,默认则是最高优先级值 -2147483648。

关于java集合类的排序再啰嗦两句。

java的集合类 collection 都会有一个sort方法,查看Collection类的源码,发现两个关键sort方法,

一个是只有一个参数的sort方法,要求返回的泛型需继承Comparable。可以重写Comparable里的compareTo方法来定义排序规则

另一个是带有两个参数的sort方法,其中第二个参数为自定义的排序器类的实例对象,这个类需要实现Comparator接口,这个排序器的用法就很多样了,支持灵活的自定义排序。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: