HandlerAdapter处理器适配器就是去调用处理器方法!
HandlerAdapter
// 解析@RequestMapping注解 生成路径和控制器方法得映射关系
RequestMappingHandlerMapping requestMappingHandlerMapping = context.getBean(RequestMappingHandlerMapping.class);// 查看生成的结果 key为路径信息 | 请求方式,value为method
Map<RequestMappingInfo, HandlerMethod> handlerMethods = requestMappingHandlerMapping.getHandlerMethods();
handlerMethods.forEach((k,v)->{System.out.println(k + "=" + v);
});// 请求来了,获取控制器方法 这里返回的不是handlerMethod返回处理器执行链,里面包括了请求的拦截器
HandlerExecutionChain chain = requestMappingHandlerMapping.getHandler(new MockHttpServletRequest("GET", "/test1"));
System.out.println(chain);// 拿到 RequestMappingHandlerAdapter
MyRequestHandlerAdapter adapter = context.getBean(MyRequestHandlerAdapter.class);
adapter.invokeHandlerMethod(new MockHttpServletRequest("GET","test1"),new MockHttpServletResponse(),(HandlerMethod) chain.getHandler());
通过RequestMappingHandlerMapping找到对应请求对应的执行链,然后使用handlerAdapter去执行这个请求对应的方法。
其中HandlerAdapter中又做了对方法参数进行解析的工作;下文中将进行介绍。
参数解析器
// 拿到适配器中的参数解析器解析请求中的参数映射到handlermethod方法上
List<HandlerMethodArgumentResolver> argumentResolvers = adapter.getArgumentResolvers();
for (HandlerMethodArgumentResolver argumentResolver : argumentResolvers) {System.out.println(argumentResolver);
}
自定义参数解析器解析@Token标注的controller
@PostMapping("/test3")
public String test3(@Token String token){log.info("test3() :{}",token);return "test3";
}
自定义参数解析器
public class TokenArgumentResolver implements HandlerMethodArgumentResolver {// 解析器是否支持某个参数 判断是否加了我们的@Token注解@Overridepublic boolean supportsParameter(MethodParameter parameter) {Token token = parameter.getParameterAnnotation(Token.class);return token != null;}// 具体解析参数@Overridepublic Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {// 拿到请求中的tokenreturn webRequest.getHeader("token");}}将参数解析器加入adapter中
@Bean
public MyRequestHandlerAdapter myRequestHandlerAdapter(){TokenArgumentResolver tokenArgumentResolver = new TokenArgumentResolver();MyRequestHandlerAdapter handlerAdapter = new MyRequestHandlerAdapter();handlerAdapter.setCustomArgumentResolvers(List.of(tokenArgumentResolver));return handlerAdapter;
}
具体执行
// 拿到 RequestMappingHandlerAdapter
MyRequestHandlerAdapter adapter = context.getBean(MyRequestHandlerAdapter.class);// 验证自定义参数解析器
MockHttpServletRequest request = new MockHttpServletRequest("POST", "/test3");
request.addHeader("token","fucku");// 拿到当前请求对应的执行链
HandlerExecutionChain executionChain = requestMappingHandlerMapping.getHandler(request);
// 执行请求对应的方法
adapter.invokeHandlerMethod(request,new MockHttpServletResponse(),(HandlerMethod) executionChain.getHandler());
返回值解析器
// 返回值解析器
List<HandlerMethodReturnValueHandler> returnValueHandlers = adapter.getReturnValueHandlers();
for (HandlerMethodReturnValueHandler returnValueHandler : returnValueHandlers) {
System.out.println(returnValueHandler);
}