视图解析
Spring MVC 的视图解析主要通过这两个接口的实现类来完成:
DispatchServlet 视图解析流程
文件路径:org/springframework/web/servlet/DispatcherServlet.java
DispatchServlet 类中含有变量
// 这里保存了所有的实体解析器@Nullableprivate 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() 方法进行视图呈现
评论