WEB
RequestMappingHandlerMapping 与 RequestMappingHandlerAdapter 俩是一对,分别用来
-
处理 @RequestMapping 映射
-
调用控制器方法、并处理方法参数与方法返回值
DispatcherServlet 初始化
-
DispatcherServlet 是在第一次被访问时执行初始化, 也可以通过配置修改为 Tomcat 启动后就初始化
-
在初始化时会从 Spring 容器中找一些 Web 需要的组件, 如 HandlerMapping、HandlerAdapter 等,并逐一调用它们的初始化
-
RequestMappingHandlerMapping 初始化时,会收集所有 @RequestMapping 映射信息,封装为 Map,其中
-
key 是 RequestMappingInfo 类型,包括请求路径、请求方法等信息
-
value 是 HandlerMethod 类型,包括控制器方法对象、控制器对象
-
有了这个 Map,就可以在请求到达时,快速完成映射,找到 HandlerMethod 并与匹配的拦截器一起返回给 DispatcherServlet
-
-
RequestMappingHandlerAdapter 初始化时,会准备 HandlerMethod 调用时需要的各个组件,如:
-
HandlerMethodArgumentResolver 解析控制器方法参数
-
HandlerMethodReturnValueHandler 处理控制器方法返回值
-
自定义参数与返回值处理器
用来解析参数上带有@taken注解的参数
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface Token {
}
public class TokenArgumentResolver implements HandlerMethodArgumentResolver {
@Override
// 是否支持某个参数
public boolean supportsParameter(MethodParameter parameter) {
Token token = parameter.getParameterAnnotation(Token.class);
return token != null;
}
@Override
// 解析参数
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
return webRequest.getHeader("token");
}
}
用来解析方法上带有@yml注解的方法,并处理方法的返回值
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Yml {
}
public class YmlReturnValueHandler implements HandlerMethodReturnValueHandler {
@Override
public boolean supportsReturnType(MethodParameter returnType) {
Yml yml = returnType.getMethodAnnotation(Yml.class);
return yml != null;
}
@Override // 返回值
public void handleReturnValue(Object returnValue, MethodParameter returnType,
ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
// 1. 转换返回结果为 yaml 字符串
String str = new Yaml().dump(returnValue);
// 2. 将 yaml 字符串写入响应
HttpServletResponse response = webRequest.getNativeResponse(HttpServletResponse.class);
response.setContentType("text/plain;charset=utf-8");
response.getWriter().print(str);
// 3. 设置请求已经处理完毕
mavContainer.setRequestHandled(true);
}
}
学到了什么
a. DispatcherServlet 是在第一次被访问时执行初始化, 也可以通过配置修改为 Tomcat 启动后就初始化
b. 在初始化时会从 Spring 容器中找一些 Web 需要的组件, 如 HandlerMapping、HandlerAdapter 等
两个最为重要的组件
a. RequestMappingHandlerAdapter, 以 @RequestMapping 作为映射路径
b. RequestMappingHandlerAdapter, 调用 handler
c. 控制器的具体方法会被当作 handler
- handler 的参数和返回值多种多样
- 需要解析方法参数, 由 HandlerMethodArgumentResolver 来做
- 需要处理方法返回值, 由 HandlerMethodReturnValueHandler 来做