流程总控 DispatcherServlet
DispatcherServlet
是 Spring MVC 中的核心组件之一,负责处理 HTTP 请求并将请求分发到适当的处理器(如控制器 Controller
)。它是一个前端控制器(Front Controller),即所有请求首先由它处理,然后根据配置将请求转发给具体的处理逻辑。
在 Spring Web 应用中,DispatcherServlet
起着至关重要的作用,它充当了整个 Web 应用的请求调度中心,负责协调请求和响应的流程。可以将它看作是整个 Spring MVC 框架的入口点。
DispatcherServlet作为一个servlet需要显示的进行配置,可以在web容器如tomcat的web.xml作为一个普通的servlet进行配置。
请求映射HandlerMapping`
HandlerMapping
的主要作用是根据 HTTP 请求的 URL 来找到与之匹配的处理器(通常是一个 @Controller
类中的方法)。HandlerMapping
的初始化是 Spring MVC 请求处理过程中非常关键的一步,它决定了 DispatcherServlet
如何定位到对应的处理方法(Handler
)。
Spring MVC 提供了多种类型的 HandlerMapping
实现,最常用的是 RequestMappingHandlerMapping
,它负责处理基于注解(如 @RequestMapping
、@GetMapping
、@PostMapping
等)的方法映射。
RequestMappingHandlerMapping:最常用的 HandlerMapping
,用于解析和处理基于注解的 URL 映射(如 @RequestMapping
、@GetMapping
、@PostMapping
)。
BeanNameUrlHandlerMapping:根据 Spring Bean 的名称来匹配请求 URL。
SimpleUrlHandlerMapping:根据静态 URL 路径进行映射。
AnnotationMethodHandlerMapping(Spring 3.x):用于处理基于注解的请求映射,通常被 RequestMappingHandlerMapping
替代。
RequestMappingHandlerMapping
会扫描所有的控制器类(即标注了 @Controller
或 @RestController
的类),并查找方法上的 @RequestMapping
注解。它会根据 @RequestMapping
中定义的 URL 路径、HTTP 方法、参数等信息,建立请求与方法之间的映射关系。
实现了InitializingBean接口,在afterPropertiesSet()方法会调用initHandlerMethods();进行注解扫描初始化。
会拿出容器中所有的bean,判断是不是handler
protected boolean isHandler(Class<?> beanType) {
return (AnnotatedElementUtils.hasAnnotation(beanType, Controller.class) ||
AnnotatedElementUtils.hasAnnotation(beanType, RequestMapping.class));
}
如果类上有Controller或RequestMapping类型的注解,就是handler。然后通过detectHandlerMethods()方法读取该handler上的mapping信息。也就是找到所有被RequestMapping注解修饰的方法。
RequestMapping注解上配置的信息会被解析成RequestMappingInfo对象存储,最后registerHandlerMethod()方法将mapping方法注册到mappingRegistry中。
/**
这里的handler就是上面的@Controller修饰的bean,method就是@RequestMapping修饰的方法,
mapping就是注解上的配置信息 ,RequestMappingInfo实例类
*/
protected void registerHandlerMethod(Object handler, Method method, T mapping) {
this.mappingRegistry.register(mapping, handler, method);
}
DispatcherServlet接收到请求后会调用doDispatch方法进行请求分发,然后拿出所有的HandlerMapping类实例调用getHandler(HttpServletRequest request)来根据请求获取可能匹配的handler进行调用。在RequestMappingHandlerMapping
实例类中最后会调用getHandlerInternal(HttpServletRequest request)方法来从mappingRegistry中获取匹配的handler进行调用处理。
请求处理HandlerAdapter
DispatcherServlet找到对应的handler处理方法后,不是直接进行调用,而是使用HandlerAdapter进行调用。根据 Handler
的类型,Spring MVC 会选择合适的 HandlerAdapter
来处理。HandlerAdapter
将请求的处理和具体的控制器方法解耦,DispatcherServlet
不需要关心控制器方法的实现细节。所有 HandlerAdapter
都实现了相同的接口,DispatcherServlet
只需要与适配器交互,而不需要关心请求的具体处理方式。它将请求和控制器方法之间的调用过程解耦。
最常用的HandlerAdapter是RequestMappingHandlerAdapter,用来处理@RequestMapping的请求。最后方法调用在invokeHandlerMethod()方法完成,它会通过反射调用方法,绑定请求参数到控制器方法的参数,处理 @RequestParam
, @PathVariable
, @RequestBody
等注解。
handleradapter会将所有请求相关信息封装成一个ServletInvocableHandlerMethod extends InvocableHandlerMethod对象,然后通过其invokeAndHandle()方法完成方法调用。
参数绑定HandlerMethodArgumentResolver
要想反射调用方法,第一步需要绑定方法调用的相关参数。HandlerMethodArgumentResolver
是 Spring MVC 中用于解析控制器方法参数的接口。每个解析器负责将 HTTP 请求中的一个参数(例如查询参数、路径变量、请求体等)绑定到控制器方法的一个参数上。
常见的HandlerMethodArgumentResolver
参数解析器:
参数解析器 | 作用 |
---|---|
RequestParamMethodArgumentResolver | 绑定 URL 查询参数或表单参数到方法参数,处理 @RequestParam 注解或无注解的参数绑定 |
PathVariableMethodArgumentResolver | 处理 @PathVariable 注解的参数绑定 |
RequestBodyMethodArgumentResolver | 处理 @RequestBody 注解的参数绑定 将请求体中的 JSON 数据绑定到方法参数 |
ModelAttributeMethodArgumentResolver | 处理 @ModelAttribute 注解的参数绑定 |
RequestHeaderMethodArgumentResolve | 绑定 HTTP 请求头中的数据到方法参数 @RequestHeader |
handlerAdapter使用参数解析器的组合类HandlerMethodArgumentResolverComposite,其中有多个不同的参数解析器,来解析不同的请求参数。解析参数具体使用的参数解析器的resolveArgument()方法。
返回值处理HandlerMethodReturnValueHandler
方法调用完后会有返回值,将控制器方法的返回值(通常是一个对象)处理成合适的响应形式(如视图、JSON 数据、XML 数据等)。这个过程主要涉及 HandlerMethodReturnValueHandler,它负责根据返回值的类型和控制器方法的注解,将返回值转换为适当的响应,并交给 DispatcherServlet
来生成最终的 HTTP 响应。
HandlerMethodReturnValueHandler
是 Spring MVC 中用于处理控制器方法返回值的接口。它负责将控制器方法的返回值处理成 HTTP 响应的最终形式。
public interface HandlerMethodReturnValueHandler {
boolean supportsReturnType(MethodParameter returnType);
void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception;
}
- supportsReturnType():判断当前处理器是否支持处理该返回值类型。
- handleReturnValue():负责将返回值处理成最终的响应。
常见的返回值处理器:
HandlerMethodReturnValueHandler 实现类 | 作用 | 处理的返回值类型 | 典型注解或场景 |
---|---|---|---|
ModelAndViewMethodReturnValueHandler | 处理 ModelAndView 类型的返回值 |
处理 ModelAndView 类型,包含视图名和模型数据,并交由 ViewResolver 解析并渲染视图。 |
ModelAndView |
ViewMethodReturnValueHandler | 处理 View 类型的返回值 |
处理 View 类型,直接返回一个视图对象,用于渲染响应。 |
View |
HttpEntityMethodReturnValueHandler | 处理 HttpEntity 或 ResponseEntity 类型的返回值 |
处理 HttpEntity 或 ResponseEntity ,包括响应的内容和状态码。 |
HttpEntity / ResponseEntity |
HttpServletResponseMethodReturnValueHandler | 处理 HttpServletResponse 类型的返回值 |
直接将返回值写入到 HttpServletResponse 对象中,用于输出流、文件等场景。 |
HttpServletResponse |
ResponseBodyMethodReturnValueHandler | 处理带 @ResponseBody 注解的方法返回值 |
将返回值序列化为 JSON、XML 或其他格式并写入响应体。 | @ResponseBody / @RestController |
ModelMethodReturnValueHandler | 处理 Model 类型的返回值 |
将返回的模型对象放入 Model 中,在视图渲染时使用。 |
Model |
RedirectViewMethodReturnValueHandler | 处理 RedirectView 类型的返回值 |
返回重定向的视图(RedirectView ),告诉浏览器进行重定向。 |
RedirectView |
ViewNameMethodReturnValueHandler | 处理 String 类型的视图名称 |
处理返回值为视图名称的情况,直接将视图名称解析为视图并渲染。 | String (视图名称) |
DeferredResultMethodReturnValueHandler | 处理 DeferredResult 类型的返回值 |
处理 DeferredResult 类型,支持异步请求响应,适用于长时间运行的请求或异步任务。 |
DeferredResult |
CallableMethodReturnValueHandler | 处理 Callable 类型的返回值 |
处理 Callable 类型,支持异步处理请求的返回值。 |
Callable |