【小家Spring】Spring MVC容器启动时,web九大组件初始化详解(Spring MVC的运行机制)(中)

简介: 【小家Spring】Spring MVC容器启动时,web九大组件初始化详解(Spring MVC的运行机制)(中)

HandlerAdapter


因为SpringMVC中的Handler可以是任意的形式,只要能处理请求就ok,但是Servlet需要的处理方法的结构却是固定的,都是以request和response为参数的方法。如何让固定的Servlet处理方法调用灵活的Handler来进行处理呢?这就是HandlerAdapter要做的事情。


Handler是用来干活的工具;HandlerMapping用于根据需要干的活找到相应的工具;HandlerAdapter是使用工具干活的人


public interface HandlerAdapter {
  //当前 HandlerAdapter 是否支持这个 Handler
  boolean supports(Object handler);
  //调用handle处理这个请求,然后返回ModelAndView 对象
  @Nullable
  ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
  long getLastModified(HttpServletRequest request, Object handler);
}


因为它和HandlerMapping联系紧密,因此且听下文分解


HandlerAdapter可以有多个


HandlerExceptionResolver


其它组件都是用来干活的。在干活的过程中难免会出现问题,出问题后怎么办呢?这就需要有一个专门的角色对异常情况进行处理,在SpringMVC中就是HandlerExceptionResolver。具体来说,此组件的作用是根据异常设置ModelAndView,之后再交给render方法进行渲染。


以前我们可以用web.xml的<error-page>标签来捕获状态码500 400的异常,但是这个已经out了,现在全局的异常都可以交给HandlerExceptionResolver去捕获处理

public interface HandlerExceptionResolver {
  @Nullable
  ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex);
}


这个接口捕获的是所有异常,而官方推荐的是使用@ExceptionHandler注解去捕获固定的异常


这个类建议交给Spring子容器管理(我们可以多实现),因为它就像一个特殊的controller


关于这块Spring MVC的全局异常的处理的一些技巧(比如页面、get、post、ajax等),请关注后面博文

RequestToViewNameTranslator


Spring MVC是通过ViewName来找到对应的视图的,而此接口的作用就是从request中获取viewName。

public interface RequestToViewNameTranslator {
  @Nullable
  String getViewName(HttpServletRequest request) throws Exception;
}


它只有一个实现,默认实现:DefaultRequestToViewNameTranslator:


  @Override
  public String getViewName(HttpServletRequest request) {
    String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);
    return (this.prefix + transformPath(lookupPath) + this.suffix);
  }
  @Nullable
  protected String transformPath(String lookupPath) {
    String path = lookupPath;
    if (this.stripLeadingSlash && path.startsWith(SLASH)) {
      path = path.substring(1);
    }
    if (this.stripTrailingSlash && path.endsWith(SLASH)) {
      path = path.substring(0, path.length() - 1);
    }
    if (this.stripExtension) {
      path = StringUtils.stripFilenameExtension(path);
    }
    if (!SLASH.equals(this.separator)) {
      path = StringUtils.replace(path, SLASH, this.separator);
    }
    return path;
  }


主要实现就是调用UrlPathHelper的getLookupPathForRequest的方法获取一个looup路径。transformPath方法主要是对获取的路径字符串再做个简单处理罢了。

所以核心是UrlPathHelper的getLookupPathForRequest的实现:

(解析路径这块,这里就不做太多的解释了,自己读读源码,相对来说比较简单)

ViewResolver


ViewResolver用来将String类型的视图名和Locale解析为View类型的视图。View是用来渲染页面的,也就是将程序返回的参数填入模板里,生成html(也可能是其它类型)文件。这里就有两个关键问题:使用哪个模板?用什么技术(规则)填入参数?这其实是ViewResolver主要要做的工作


ViewResolver需要找到渲染所用的模板和所用的技术(也就是视图的类型)进行渲染,具体的渲染过程则交由不同的视图自己完成。


public interface ViewResolver {
  @Nullable
  View resolveViewName(String viewName, Locale locale) throws Exception;
}


image.png

1.AbstractCachingViewResolver 基于缓存的抽象视图解析器


2.UrlBasedViewResolver 实现了缓存 提供了prefix suffix拼接的url视图解析器。


3.InternalResourceViewResolver 基于url 的内部资源视图解析器。


4.XmlViewResolver 基于xml的缓存视图解析器


5.BeanNameViewResolver beanName来自容器,并且不支持缓存。


6.ResourceBundleViewResolver 这个有点复杂


7.reeMarkerViewResolver、VolocityViewResolver 都基于url 但会解析成特定的view

实现类也非常的多,在Spring MVC里是一个非常非常重要的概念(比如什么时候返回页面,什么时候返回json呢?),因此后面会有专门的文章进行深入解读


ViewResolverComposite简单来说就是使用简单的List来保存你配置使用的视图解析器。


ViewResolvers可以有多个

FlashMapManager


用来管理FlashMap的,FlashMap主要用在redirect中传递参数。

public interface FlashMapManager {
    @Nullable
    FlashMap retrieveAndUpdate(HttpServletRequest var1, HttpServletResponse var2);
    void saveOutputFlashMap(FlashMap var1, HttpServletRequest var2, HttpServletResponse var3);
}


image.png


可以看出结构图非常简单,抽象类采用模板模式定义整个流程,具体实现类用SessionFlashMapManager通过模板方法提供了具体操作FlashMap的功能。

功能说明:


  • 实际的Session中保存的FlashMap是List类型,也就是说一个Session可以保存多个FlashMap,一个FlashMap保存着一套Redirect转发所传递的参数
  • FlashMap继承自HashMap,除了用于HashMap的功能和设置有效期,还可以保存Redirect后的目标路径和通过url传递的参数,这两项内容主要用来从Session保存的多个FlashMap中查找当前的FalshMap


具体请持续关注吧,后面再详说


至此,SpringMVC中的9大组件也就简单地概述了一遍。通过对此9大组件的宏观认识,对分析SpringMVC的设计、原理与实现都会有很大的帮助作用。


onRefresh(wac) / initStrategies(wac)详解

这可以说是DisparcherServlet初始化时的核心逻辑


initMultipartResolver

  private void initMultipartResolver(ApplicationContext context) {
    try {
      this.multipartResolver = context.getBean(MULTIPART_RESOLVER_BEAN_NAME, MultipartResolver.class);
    } catch (NoSuchBeanDefinitionException ex) {
      this.multipartResolver = null;
    }
  }


这个很简单,若我们向容器里配置了此Bean就有,否则默认是不支持文件上传的

备注:注意配置此些配型Bean的名称,都是有固定值的,请必须保证一样,否则你的配置将不生效。下同

相关文章
|
5月前
|
XML Java 测试技术
《深入理解Spring》:IoC容器核心原理与实战
Spring IoC通过控制反转与依赖注入实现对象间的解耦,由容器统一管理Bean的生命周期与依赖关系。支持XML、注解和Java配置三种方式,结合作用域、条件化配置与循环依赖处理等机制,提升应用的可维护性与可测试性,是现代Java开发的核心基石。
|
5月前
|
XML Java 应用服务中间件
【SpringBoot(一)】Spring的认知、容器功能讲解与自动装配原理的入门,带你熟悉Springboot中基本的注解使用
SpringBoot专栏开篇第一章,讲述认识SpringBoot、Bean容器功能的讲解、自动装配原理的入门,还有其他常用的Springboot注解!如果想要了解SpringBoot,那么就进来看看吧!
599 2
|
XML Java 数据格式
京东一面:spring ioc容器本质是什么? ioc容器启动的步骤有哪些?
京东一面:spring ioc容器本质是什么? ioc容器启动的步骤有哪些?
|
5月前
|
算法 Java Go
【GoGin】(1)上手Go Gin 基于Go语言开发的Web框架,本文介绍了各种路由的配置信息;包含各场景下请求参数的基本传入接收
gin 框架中采用的路优酷是基于httprouter做的是一个高性能的 HTTP 请求路由器,适用于 Go 语言。它的设计目标是提供高效的路由匹配和低内存占用,特别适合需要高性能和简单路由的应用场景。
471 4
|
9月前
|
缓存 JavaScript 前端开发
鸿蒙5开发宝藏案例分享---Web开发优化案例分享
本文深入解读鸿蒙官方文档中的 `ArkWeb` 性能优化技巧,从预启动进程到预渲染,涵盖预下载、预连接、预取POST等八大优化策略。通过代码示例详解如何提升Web页面加载速度,助你打造流畅的HarmonyOS应用体验。内容实用,按需选用,让H5页面快到飞起!
|
9月前
|
JavaScript 前端开发 API
鸿蒙5开发宝藏案例分享---Web加载时延优化解析
本文深入解析了鸿蒙开发中Web加载完成时延的优化技巧,结合官方案例与实际代码,助你提升性能。核心内容包括:使用DevEco Profiler和DevTools定位瓶颈、四大优化方向(资源合并、接口预取、图片懒加载、任务拆解)及高频手段总结。同时提供性能优化黄金准则,如首屏资源控制在300KB内、关键接口响应≤200ms等,帮助开发者实现丝般流畅体验。
|
前端开发 JavaScript Shell
鸿蒙5开发宝藏案例分享---Web页面内点击响应时延分析
本文为鸿蒙开发者整理了Web性能优化的实战案例解析,结合官方文档深度扩展。内容涵盖点击响应时延核心指标(≤100ms)、性能分析工具链(如DevTools时间线、ArkUI Trace抓取)以及高频优化场景,包括递归函数优化、网络请求阻塞解决方案和setTimeout滥用问题等。同时提供进阶技巧,如首帧加速、透明动画陷阱规避及Web组件初始化加速,并通过优化前后Trace对比展示成果。最后总结了快速定位问题的方法与开发建议,助力开发者提升Web应用性能。
|
9月前
|
JSON 开发框架 自然语言处理
【HarmonyOS Next之旅】基于ArkTS开发(三) -> 兼容JS的类Web开发(三)
本文主要介绍了应用开发中的三大核心内容:生命周期管理、资源限定与访问以及多语言支持。在生命周期部分,详细说明了应用和页面的生命周期函数及其触发时机,帮助开发者更好地掌控应用状态变化。资源限定与访问章节,则聚焦于资源限定词的定义、命名规则及匹配逻辑,并阐述了如何通过 `$r` 引用 JS 模块内的资源。最后,多语言支持部分讲解了如何通过 JSON 文件定义多语言资源,使用 `$t` 和 `$tc` 方法实现简单格式化与单复数格式化,为全球化应用提供便利。
323 104
|
9月前
|
JavaScript 前端开发 API
【HarmonyOS Next之旅】基于ArkTS开发(三) -> 兼容JS的类Web开发(二)
本文介绍了HarmonyOS应用开发中的HML、CSS和JS语法。HML作为标记语言,支持数据绑定、事件处理、列表渲染等功能;CSS用于样式定义,涵盖尺寸单位、样式导入、选择器及伪类等特性;JS实现业务逻辑,包括ES6语法支持、对象属性、数据方法及事件处理。通过具体代码示例,详细解析了页面构建与交互的实现方式,为开发者提供全面的技术指导。
331 104
|
9月前
|
开发框架 编解码 JavaScript
【HarmonyOS Next之旅】基于ArkTS开发(三) -> 兼容JS的类Web开发(一)
该文档详细介绍了一个兼容JS的类Web开发范式的方舟开发框架,涵盖概述、文件组织、js标签配置及app.js等内容。框架采用HML、CSS、JavaScript三段式开发方式,支持单向数据绑定,适合中小型应用开发。文件组织部分说明了目录结构、访问规则和媒体文件格式;js标签配置包括实例名称、页面路由和窗口样式信息;app.js则描述了应用生命周期与对象管理。整体内容旨在帮助开发者快速构建基于方舟框架的应用程序。
348 102