image.png

AbstractHandlerMapping

初始化HandlerInterceptor

AbstractHandlerMapping extends WebApplicationObjectSupport
WebApplicationObjectSupport extends ApplicationObjectSupport
ApplicationObjectSupport implements ApplicationContextAware
所以,AbstractHandlerMapping 初始化时会调用initApplicationContext()。

初始化Interceptors放入HandlerMapping中。

AbstractHandlerMethodMapping

初始化HandlerMethodMapping信息

implements InitializingBean

所以会初始化时候执行 initHandlerMethods()
HandlerMapping - 图2

  • 首先要满足@Controller || @RequestMapping

image.png

  • 解析出 ,放入MappingRegistry。

image.png

MappingRegistry

  • urlLookup:Url -> RequestMappingInfos
  • mappingLookup:RequestMappingInfo -> HandlerMethod

image.png
这里的T 对于RequestMappingHandlerMapping来说就是RequestMappingInfo
RequestMappingInfo顾名思义Mapping信息。
HandlerMapping通过Url找到RequestMappingInfo,再通过RequestMappingInfo找到HandlerMethod

RequestMappingHandlerMapping

RequestMappingInfo【Condition集合

RequestMappingInfo是Condition集合,其中有关于@RequestMapping的各种Condition,还有一个CustomCondition,判断的时候也会判断该Condition是否成立。
HandlerMapping - 图6

自定义RequestMappingHandlerMapping

HandlerMapping - 图7

第一步:重写getCustomMethodCondition()

根据method返回需要的RequestCondition
image.png

第二步:自定义AbstractRequestCondition

  1. /**
  2. * 匹配api请求条件的 RequestCondition
  3. * @author HP
  4. *
  5. */
  6. public class ApiRequestCondition extends AbstractRequestCondition<ApiRequestCondition> {
  7. private final Set<String> cmds;
  8. public ApiRequestCondition(String... cmds) {
  9. this(Arrays.asList(cmds));
  10. }
  11. private ApiRequestCondition(Collection<String> cmds) {
  12. this.cmds = Collections.unmodifiableSet(new HashSet<String>(cmds));
  13. }
  14. /**
  15. * @ApiCmdMapping.java 注解值处理方法级的 所以 用不到combine
  16. */
  17. @Override
  18. public ApiRequestCondition combine(ApiRequestCondition other) {
  19. this.cmds.addAll(other.cmds);
  20. return new ApiRequestCondition(cmds);
  21. }
  22. /**
  23. * 获取匹配条件,如果return null 时表明不匹配
  24. */
  25. @Override
  26. public ApiRequestCondition getMatchingCondition(HttpServletRequest request) {
  27. Req_header reqHeader = null;
  28. String reqStr = null;
  29. // 转成Req_header,统一验证、处理等
  30. try {
  31. reqStr = IOUtils.toString(request.getInputStream());
  32. JSONObject reqJson = JSON.parseObject(reqStr);
  33. JSONObject header_json = reqJson.getJSONObject("Req_Header");
  34. reqHeader = JSON.toJavaObject(header_json, Req_header.class);
  35. String cmd = reqHeader.getCmd();
  36. if(cmd != null && !"".equals(cmd)){
  37. if(cmds.contains(cmd)){
  38. return this;
  39. }else {
  40. return null;
  41. }
  42. } else {
  43. return null;
  44. }
  45. } catch (Exception e) {
  46. e.printStackTrace();
  47. return null;
  48. }
  49. }
  50. /**
  51. * 比较哪个条件为最优匹配(由于只有cmd一个条件所以不允许重复注解相同的cmd)
  52. */
  53. public int compareTo(ApiRequestCondition other, HttpServletRequest request) {
  54. return 0;
  55. }
  56. @Override
  57. protected Collection<?> getContent() {
  58. return cmds;
  59. }
  60. @Override
  61. protected String getToStringInfix() {
  62. return " || ";
  63. }
  64. }

查找HandlerMethod过程

1. 根据url找到RequestMappingInfo

image.png

2. 判断这些RequestMappingInfo(Condition)是否符合当前请求

依次判断RequestMappingInfo内部的Condition是否满足当前请求。
ApiRequestCondition#getMatchingCondition
image.png
image.png

3. 根据匹配的RequestMappingInfo找到对应的HandlerMethod

image.png

HandlerMapping返回值

HandlerExecutionChain包含HandlerMethod 和 HandlerInterceptor