DispatcherServlet-静态资源服务原理(四)

简介: 在请求静态资源文件的时候,Spring内部是如何实现的呢?之前对这个问题,有疑问,但如果是自己处理静态的资源都是统一的使用IOUtils.copy(input,output)中去,想了解下Spring内部是如何做的。

在请求静态资源文件的时候,Spring内部是如何实现的呢?之前对这个问题,有疑问,但如果是自己处理静态的资源都是统一的使用IOUtils.copy(input,output)中去,想了解下Spring内部是如何做的。

带着疑问阅读下源码,果不其然,一起看下

分析

之前我们提到了DispatcherServlet的doDispatcher大致流程,这次我们以静态资源文件为例,再看下。

  1. 在dispatcher-servlet.xml配置文件里面,配置静态资源的路径。然后在js目录下新建一个index.js文件
<mvc:resources mapping="/js/**" location="/js/" />
  1. 启动项目,调试在getHandler这一步,我们可以看到配置的HandlerMappings,其中SimpleUrlHandlerMapping是我们在xml配置文件中配置的,我们写几个resource的映射,就有几个SimpleUrlHandlerMapping对象。
img_38842a21474653adfa1ba5be20489ddb.png
image.png

像RequestMappingHandlerMapping,根据请求的路径获取Bean对应的HandlerMethod,然后封装。
BeanNameUrlHandlerMapping再调试的时候还未遇到。
SimpleUrlHandlerMapping根据我们在配置文件里面的定义,可以看到获取到对应的ResourceHttpRequestHandler.


img_998f4c17fc7fa837c4ed645e3b683715.png
image.png
  1. 获取静态资源的HandlerAdpater. 这些都是之前分析doDispatch提到的


    img_5f56bec215d370573f2e2a30744bb9af.png
    image.png

三个不同的Adpater内部实现的support机制不同,如果support返回true则获得对应的Adapter.
支持ResourceHttpRequestHandler的Handler只有HttpRequestHandlerAdapter,看他们的名字差不多就可以对应上来。

  1. 拦截器预处理,不多说了
  2. 进行处理HanderAdapter.handler(request,response,handler)
    静态资源的HandlerAdpater处理很少,直接交给Handler进行的处理,没有额外的操作。


    img_cad7f0de5af7cd30afd822ced410b114.png
    image.png

handleRequest内部处理如下:

  • getResource获取路径对应的静态资源,文件
  • 检查请求是否合法
  • 判断是否要加cache的Http Header
  • 根据Http是否有Range头部,不管有无,都通过StreamUtils进行流拷贝。中间又利用到ResourceHttpMessageConverter.

HttpMessageConterver可以转换Request和Response的一些内容,细节以后再讨论

img_b3cfde88e02654a7b768e10009f19d9a.png
image.png
  1. 将静态资源文件通过流的方式输出到输出流之后,ModelAndView值为null,所以不会对视图进行处理

  2. Handler的拦截器进行postHandler处理,之前提到过,这里不多说了。

  3. 处理分发结果,errorView,exception,modelandview都为null,也就是都不处理,最后进行拦截器的triggerAfterCompletion操作

  4. 进行最后的清理工作,请求完成

回顾

如果明白doDispatcher的流程之后,再去看静态资源的处理,就简单很多,因为服务静态资源也是doDispatch的一部分。

服务静态资源简单来说:
首先,根据我们定义的resorce映射,内部会创建SimpleUrlHandler,在获取到Handler之后,静态资源的HandlerAdpater也比较简单,它的Adpater仍然是把操作交给Handler处理。

Handler内部因为是静态资源,没有太多的逻辑操作,只是对Http的请求头做一些判断,最后都是由ResourceHttpMessageConverter将资源通过流的方式输出到Resouce.

后续基本上只是拦截器稍微工作一下,其余基本上都是跳过的操作

总结

Spring MVC对静态资源的处理,相对简单一些。

相关文章
|
前端开发 Java 应用服务中间件
配置SpringMVC的前端控制器DispatcherServlet时,<url-pattern>中“/“和“/*“的区别
配置SpringMVC的前端控制器DispatcherServlet时,<url-pattern>中“/“和“/*“的区别
|
XML 存储 前端开发
02创建DispatcherServlet来处理所有的请求
1.Servlet的生命周期 2.DispatcherServlet的类结构体系 3.让DispatcherServlet来处理所有的请求
257 0
|
前端开发
前端控制器:SpringMVC执行流程(DispatcherServlet解读)
前端控制器:SpringMVC执行流程(DispatcherServlet解读)
126 0
前端控制器:SpringMVC执行流程(DispatcherServlet解读)
|
前端开发
DispatcherServlet源码注解分析
DispatcherServlet源码注解分析
149 0
|
设计模式 开发框架 前端开发
SpringMVC源码解析DispatcherServlet#doDispatch方法流程(上)
SpringMVC源码解析DispatcherServlet#doDispatch方法流程(上)
253 0
SpringMVC源码解析DispatcherServlet#doDispatch方法流程(上)
SpringMVC源码解析DispatcherServlet#doDispatch方法流程(下)
SpringMVC源码解析DispatcherServlet#doDispatch方法流程(下)
305 0
SpringMVC源码解析DispatcherServlet#doDispatch方法流程(下)
|
前端开发 Java Spring
DispatcherServlet源码分析
DispatcherServlet处理request DispatcherServlet是前端控制器, Spring MVC遵循前端控制器模式,前端控制器是MVC 模式中C的一部分, 除此之外,C还包括我们定义的Controller等应用控制器类。
751 0
DispatcherServlet请求流程解析-doDispatch(三)
上篇文章我们主要看了DispatcherServlet在提供服务之间做的初始化工作,大部门工作都在WebApplicationContext中完成,然后WebApplicationContext是DispatcherServlet的一个属性。
|
Java Spring 容器
DispatcherServlet请求流程解析-initWebApplicationContext(二)
上面一篇文章提到,在Servlet初始化的时候,获取属性后调用initServletBean,这个方法会initWebApplicationContext,这是DispatcherServlet对后面的处理做了很多的预先准备工作,我们一起来看看它到底做了什么事情。
|
前端开发 Java Spring
SpringMVC的DispatcherServlet的默认策略
SpringMVC的DispatcherServlet的默认策略 在使用SpringMVC的时候,我们知道需要HandlerMapping定义请求路径与处理器之间的映射,需要HandlerAdapter来调用处理器方法并返回一个ModelAndView对象,需要ViewResolver来解析视图。
1953 0