DispatcherServlet 简单介绍
继续缝缝补补
原文 An Intro to the Spring DispatcherServlet
Introduction 不展开
DispatcherServlet Request Processing
原文:Essentially, a DispatcherServlet handles an incoming HttpRequest, delegates the request, and processes that request according to the configured HandlerAdapter interfaces that have been implemented within the Spring application along with accompanying annotations specifying handlers, controller endpoints, and response objects.
Let’s get more in-depth about how a DispatcherServlet processes a component:
the WebApplicationContext associated to a DispatcherServlet under the key DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE is searched for and made available to all of the elements of the process
The DispatcherServlet finds all implementations of the HandlerAdapter interface configured for your dispatcher using getHandler() – each found and configured implementation handles the request via handle() through the remainder of the process
the LocaleResolver is optionally bound to the request to enable elements in the process to resolve the locale
the ThemeResolver is optionally bound to the request to let elements, such as views, determine which theme to use
if a MultipartResolver is specified, the request is inspected for MultipartFiles – any found are wrapped in a MultipartHttpServletRequest for further processing
HandlerExceptionResolver implementations declared in the WebApplicationContext picks up exceptions that are thrown during processing of the requestHandlerAdapter Interfaces 不展开
在详细解读dispatcherServlet是如何处理请求之前,我们需要先建立一个spring mvc工作的流程:
浏览器
│
│ HTTP Request
▼
DispatcherServlet
│
│ 找:这个 URL 应该交给谁?
▼
HandlerMapping(根据 请求找到对应的handler)
│
│ 找到 Controller 方法
▼
Handler
│
│ 但是 Controller 方法怎么调用?
▼
HandlerAdapter(handler调用适配器,DispatcherServlet通过HandleAdapter调用Handler)
│
│ 调用
▼
Controller 方法
│
│ 返回结果
▼
DispatcherServlet
│
▼
HTTP Response
原文翻译:
- DispatcherServlet 的请求处理
本质上,DispatcherServlet 接收一个传入的 HttpRequest,然后根据 Spring 应用中配置好的 HandlerAdapter 接口实现,以及相关的注解(这些注解用于声明处理器、Controller 端点和响应对象),将请求委派出去并对请求进行处理。
这段话交代了DispatcherServlet的职责:接受http请求,调度HandlerMapping找到handler,调度HandlerAdapter调用Handler响应请求。它自己只负责调度,将任务委托给其他模块。
进一步来看,DispatcherServlet 处理一个组件/请求时,大致会经历以下过程:
首先,会查找与 DispatcherServlet 关联的 WebApplicationContext。这个上下文会以 DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE 为 key 保存,并提供给整个处理流程中的各个组件使用。
DispatcherServlet 会通过 getHandler() 找到当前 Dispatcher 配置的 HandlerAdapter 实现。找到合适的实现后,在后续处理过程中通过它的 handle() 方法来处理请求。
这段话具体解释HandlerMapping是如何工作的,它通过WebApplicationContext(也就是我们一开始就讲到的spring容器,还记得@Bean public CommandLineRunner demo(CustomerRepository repository){}这个方法吗?就是从这里我们开始了解到Spring容器ApplicationContext的,它里面有所有的Bean等)找到对应的Handler,
如果配置了 LocaleResolver,它会被绑定到当前请求,使处理流程中的其他组件能够确定当前请求所对应的语言/地区(Locale)。
如果配置了 ThemeResolver,它会被绑定到当前请求,使诸如 View 之类的组件能够确定应该使用什么主题。
如果配置了 MultipartResolver,Spring 会检查当前请求是否包含 MultipartFile(例如文件上传)。如果存在,就会把原始请求包装成 MultipartHttpServletRequest,供后续处理。
在请求处理过程中,如果抛出了异常,那么在 WebApplicationContext 中声明的 HandlerExceptionResolver 实现会负责处理这些异常。
在理解了这些之后,我们把这个和之前学过的Controller拼接起来,形成spring mvc 处理请求的完整链路:
Tomcat
↓
DispatcherServlet
↓
HandlerMapping
↓
Handler
↓
HandlerAdapter
↓
Controller
↓
返回值处理
↓
HttpMessageConverter
↓
HTTP Response