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

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 【小家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月前
|
人工智能 JSON 安全
Spring Boot实现无感刷新Token机制
本文深入解析在Spring Boot项目中实现JWT无感刷新Token的机制,涵盖双Token策略、Refresh Token安全性及具体示例代码,帮助开发者提升用户体验与系统安全性。
570 5
|
1月前
|
缓存 安全 Java
《深入理解Spring》过滤器(Filter)——Web请求的第一道防线
Servlet过滤器是Java Web核心组件,可在请求进入容器时进行预处理与响应后处理,适用于日志、认证、安全、跨域等全局性功能,具有比Spring拦截器更早的执行时机和更广的覆盖范围。
|
3月前
|
Ubuntu PHP Docker
一个可以运行的Dockerfile_php ,用来创建php容器镜像
该简介描述了一个基于 Dragonwell 8 Ubuntu 的 Docker 镜像,用于构建包含 PHP 7.4 及常用扩展的运行环境。通过更换为阿里云源提升安装速度,配置了 PHP-FPM 并暴露 9000 端口,使用自定义 Dockerfile 构建镜像并成功运行容器。
|
4月前
|
JSON 前端开发 Java
Spring MVC 核心组件与请求处理机制详解
本文解析了 Spring MVC 的核心组件及请求流程,核心组件包括 DispatcherServlet(中央调度)、HandlerMapping(URL 匹配处理器)、HandlerAdapter(执行处理器)、Handler(业务方法)、ViewResolver(视图解析),其中仅 Handler 需开发者实现。 详细描述了请求执行的 7 步流程:请求到达 DispatcherServlet 后,经映射器、适配器找到并执行处理器,再通过视图解析器渲染视图(前后端分离下视图解析可省略)。 介绍了拦截器的使用(实现 HandlerInterceptor 接口 + 配置类)及与过滤器的区别
385 0
|
9月前
|
人工智能 Prometheus 监控
容器化AI模型的监控与治理:确保模型持续稳定运行
在前几篇文章中,我们探讨了AI模型的容器化部署及构建容器化机器学习流水线。然而,将模型部署到生产环境只是第一步,更重要的是确保其持续稳定运行并保持性能。为此,必须关注容器化AI模型的监控与治理。 监控和治理至关重要,因为AI模型在生产环境中面临数据漂移、概念漂移、模型退化和安全风险等挑战。全面的监控涵盖模型性能、数据质量、解释性、安全性和版本管理等方面。使用Prometheus和Grafana可有效监控性能指标,而遵循模型治理最佳实践(如建立治理框架、定期评估、持续改进和加强安全)则能进一步提升模型的可信度和可靠性。总之,容器化AI模型的监控与治理是确保其长期稳定运行的关键。
|
8月前
|
存储 监控 对象存储
ACK 容器监控存储全面更新:让您的应用运行更稳定、更透明
ACK 容器监控存储全面更新:让您的应用运行更稳定、更透明
251 0
ACK 容器监控存储全面更新:让您的应用运行更稳定、更透明
|
9月前
|
存储 监控 对象存储
ACK 容器监控存储全面更新:让您的应用运行更稳定、更透明
ACK 容器监控存储全面更新:让您的应用运行更稳定、更透明
191 1
|
9月前
|
PHP Docker 容器
如何在宿主主机运行容器中的php守护进程
在Docker容器中同时运行多个程序(如Nginx+PHP+Ftp)时,需用`docker exec`命令启动额外服务。首先通过`php -v`查看PHP版本,再用`which php-fpm7.4`确认PHP安装路径,通常返回`/usr/sbin/php-fpm7.4`。最后直接运行该路径启动PHP-FPM服务,确保其正常工作。
179 14
|
开发框架 前端开发 .NET
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
435 0
|
存储 开发框架 前端开发
[回馈]ASP.NET Core MVC开发实战之商城系统(五)
经过一段时间的准备,新的一期【ASP.NET Core MVC开发实战之商城系统】已经开始,在之前的文章中,讲解了商城系统的整体功能设计,页面布局设计,环境搭建,系统配置,及首页【商品类型,banner条,友情链接,降价促销,新品爆款】,商品列表页面,商品详情等功能的开发,今天继续讲解购物车功能开发,仅供学习分享使用,如有不足之处,还请指正。
325 0