陈时陈事随风飘,
兴亡兴悲天行道.
来忧来喜不计较,
书好书坏自逍遥.

SpringMVC 之DispatchServlet 原理梳理

DispatchServlet

主要梳理了一下源码中几个方法

启动时:onRefresh()

初始化各种配置 initStrategies()

  • this.initMultipartResolver(context);

  • this.initLocaleResolver(context);

  • this.initThemeResolver(context);

  • this.initHandlerMappings(context);

  • this.initHandlerAdapters(context);

  • this.initHandlerExceptionResolvers(context);

  • this.initRequestToViewNameTranslator(context);

  • this.initViewResolvers(context);

  • this.initFlashMapManager(context);

请求时:doService()

doDispatch()

根据请求选择合适的HandlerExecutionChain mappedHandler = this.getHandler(processedRequest);

遍历所有初始化的HanderMapping.getHandler()
  1. SimpleUrlHanderMapping

  2. PropertySourcedRequestMappinglHanderMapping

  3. RequestMappinglHanderMapping

  • 父类:AbstractHandlerMethodMapping .getHandlerInternal(request)

  • 根据请求路径 lookupPath 获取对应的controller的方法 lookupHandlerMethod(String lookupPath, HttpServletRequest request)

    1. 其实初始化的时候就已经把RequestMap储存到集合中了 所以第一步先根据key找这个集合 this.urlLookup 获取RequestMappingInfo

    2. 如果没有找到,再遍历这个进行匹配 this.mappingLookup 可以匹配到具体的HandMethod

      • 匹配规则:RequestMappingInfo .getMatchingCondition(HttpServletRequest request)
  1. BeanNameHanderMapping

  2. SimpleUrlHanderMapping 居然有第二个?

  3. WelcomePageHanderMapping

再根据hander选择适配器 HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());

执行拦截器HandlerInterceptor前置方法 mappedHandler.applyPreHandle(processedRequest, response)

通过适配器执行具体内容 mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

  1. HttpRequestHandlerAdapter:

  2. RequestMappingHandlerAdapter:

  • 会调用该方法 handleInternal()

  • 执行具体的方法invokeHandlerMethod mav = this.invokeHandlerMethod(request, response, handlerMethod);

  • ServletInvocableHandlerMethod.class invocableMethod.invokeAndHandle(webRequest, mavContainer);

  • InvocableHandlerMethod.class Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);

    1. 获取请求参数 Object[] args = this.getMethodArgumentValues(request, mavContainer, providedArgs);

      • 会先从privatedArgs中取看看,但是一般都是取不到的 args[i] = findProvidedArgument(parameter, providedArgs);

      • args[i] = this.resolvers.resolveArgument(parameter, mavContainer, request, this.dataBinderFactory);

      * HandlerMethodArgumentResolverComposite.class resolveArgument()

      * 根据参数从this.argumentResolvers中指定解析器 HandlerMethodArgumentResolver resolver = getArgumentResolver(parameter);

      * 使用解析指定解析器 获取参数 resolver.resolveArgument(parameter, mavContainer, webRequest, binderFactory);

    2. 调用执行方法 this.doInvoke(args);

  1. SimpleControllerHandlerAdapter

  2. 一般不用被初始化,只有上面三个 SimpleServletHandlerAdapter: servlet时使用

执行拦截器HandlerInterceptor后置方法 mappedHandler.applyPostHandle(processedRequest, response, mv);

posted @ 2019-10-17 15:30  thinline未来  阅读(270)  评论(0)    收藏  举报