写点什么

Spring 视图解析流程

发布于: 2020 年 12 月 05 日

视图解析


Spring MVC 的视图解析主要通过这两个接口的实现类来完成:


  • ViewResolver

  • View


DispatchServlet 视图解析流程


文件路径:org/springframework/web/servlet/DispatcherServlet.java


DispatchServlet 类中含有变量


// 这里保存了所有的实体解析器@Nullableprivate List<ViewResolver> viewResolvers;
复制代码


  1. 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,并加载到应用上下文


  1. 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);    }  }}
复制代码


  1. 在取得 View 后,会调用具体实现类的 render() 方法进行视图呈现


用户头像

你们看不见我 2018.03.26 加入

你们看不见我

评论

发布
暂无评论
Spring视图解析流程