spring mvc允许注册多个viewResolver。spring mvc通过循环调用viewResolver解析View。View不为空则直接返回。相应代码在DispatcherServlet中
protected View resolveViewName(String viewName, Map<String, Object> model, Locale locale,
HttpServletRequest request) throws Exception {
for (ViewResolver viewResolver : this.viewResolvers) {
View view = viewResolver.resolveViewName(viewName, locale);
if (view != null) {
return view;
}
}
return null;
}
viewResolvers是List集合。由于List是有序的,所以viewResolvers的顺序很重要。使用spring boot自动配置viewResolver的话,ContentNegotiatingViewResolver将会是第一个元素。相应代码在WebMvcAutoConfigurationAdapter中
@Bean
@ConditionalOnBean(ViewResolver.class)
@ConditionalOnMissingBean(name = "viewResolver", value = ContentNegotiatingViewResolver.class)
public ContentNegotiatingViewResolver viewResolver(BeanFactory beanFactory) {
ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();
resolver.setContentNegotiationManager(
beanFactory.getBean(ContentNegotiationManager.class));
// ContentNegotiatingViewResolver uses all the other view resolvers to locate
// a view so it should have a high precedence
resolver.setOrder(Ordered.HIGHEST_PRECEDENCE);
return resolver;
}
见注释,ContentNegotiatingViewResolver使用所有其他的view resolvers定位view,所以它有最高的优先级