视图解析
Spring MVC 的视图解析主要通过这两个接口的实现类来完成:
DispatchServlet 视图解析流程
文件路径:org/springframework/web/servlet/DispatcherServlet.java
DispatchServlet 类中含有变量
// 这里保存了所有的实体解析器
@Nullable
private List<ViewResolver> viewResolvers;
复制代码
void initStrategies(ApplicationContext context)
protected void initStrategies(ApplicationContext context) {
initMultipartResolver(context);
initLocaleResolver(context);
initThemeResolver(context);
initHandlerMappings(context);
initHandlerAdapters(context);
initHandlerExceptionResolvers(context);
initRequestToViewNameTranslator(context);
initViewResolvers(context);
initFlashMapManager(context);
}
/**
* Initialize the ViewResolvers used by this class.
* <p>If no ViewResolver beans are defined in the BeanFactory for this
* namespace, we default to InternalResourceViewResolver.
*/
private void initViewResolvers(ApplicationContext context) {
this.viewResolvers = null;
if (this.detectAllViewResolvers) {
// Find all ViewResolvers in the ApplicationContext, including ancestor contexts.
// 从BeanFactory中取得了所有的 ViewResolver.class 的 Bean
Map<String, ViewResolver> matchingBeans =
BeanFactoryUtils.beansOfTypeIncludingAncestors(context, ViewResolver.class, true, false);
if (!matchingBeans.isEmpty()) {
this.viewResolvers = new ArrayList<>(matchingBeans.values());
// We keep ViewResolvers in sorted order.
AnnotationAwareOrderComparator.sort(this.viewResolvers);
}
}
else {
try {
ViewResolver vr = context.getBean(VIEWRESOLVERBEAN_NAME, ViewResolver.class);
this.viewResolvers = Collections.singletonList(vr);
}
catch (NoSuchBeanDefinitionException ex) {
// Ignore, we'll add a default ViewResolver later.
}
}
// Ensure we have at least one ViewResolver, by registering
// a default ViewResolver if no other resolvers are found.
if (this.viewResolvers == null) {
this.viewResolvers = getDefaultStrategies(context, ViewResolver.class);
if (logger.isTraceEnabled()) {
logger.trace("No ViewResolvers declared for servlet '" + getServletName() +
"': using default strategies from DispatcherServlet.properties");
}
}
}
复制代码
初始化的时候会初始化所有的 ViewResolver,并加载到应用上下文
void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception
ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
复制代码
这个 handle 中会处理 request 请求,会调用我们实际的 controller 并将结果返回处理成 modelAndView 类型返回
void processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
复制代码
在 doDispatch
方法中会调用processDispatchResult
做视图名到视图的解析。
- 其中如果没有返回视图会尝试 RequestToViewNameTranslator
private void applyDefaultViewName(HttpServletRequest request, @Nullable ModelAndView mv) throws Exception {
if (mv != null && !mv.hasView()) {
String defaultViewName = getDefaultViewName(request);
if (defaultViewName != null) {
mv.setViewName(defaultViewName);
}
}
}
复制代码
- Mono<View> resolveViewName(String viewName, Locale locale)
解析 view 对象
/**
* Do we need view name translation?
*/
private void applyDefaultViewName(HttpServletRequest request, @Nullable ModelAndView mv) throws Exception {
if (mv != null && !mv.hasView()) {
String defaultViewName = getDefaultViewName(request);
if (defaultViewName != null) {
mv.setViewName(defaultViewName);
}
}
}
复制代码
在取得 View 后,会调用具体实现类的 render()
方法进行视图呈现
评论