SpringMVC 之DispatchServlet 原理梳理
- DispatchServlet
- 启动时:onRefresh()
- 请求时:doService()
- doDispatch()
- 根据请求选择合适的HandlerExecutionChain mappedHandler = this.getHandler(processedRequest);
- 再根据hander选择适配器 HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
- 执行拦截器HandlerInterceptor前置方法 mappedHandler.applyPreHandle(processedRequest, response)
- 通过适配器执行具体内容 mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
- 执行拦截器HandlerInterceptor后置方法 mappedHandler.applyPostHandle(processedRequest, response, mv);
- doDispatch()
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()
-
SimpleUrlHanderMapping -
PropertySourcedRequestMappinglHanderMapping -
RequestMappinglHanderMapping
-
父类:AbstractHandlerMethodMapping .getHandlerInternal(request) -
根据请求路径 lookupPath 获取对应的controller的方法 lookupHandlerMethod(String lookupPath, HttpServletRequest request)-
其实初始化的时候就已经把RequestMap储存到集合中了 所以第一步先根据key找这个集合 this.urlLookup 获取RequestMappingInfo
-
如果没有找到,再遍历这个进行匹配 this.mappingLookup 可以匹配到具体的HandMethod- 匹配规则:RequestMappingInfo .getMatchingCondition(HttpServletRequest request)
-
-
BeanNameHanderMapping -
SimpleUrlHanderMapping 居然有第二个? -
WelcomePageHanderMapping
再根据hander选择适配器 HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
执行拦截器HandlerInterceptor前置方法 mappedHandler.applyPreHandle(processedRequest, response)
通过适配器执行具体内容 mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
-
HttpRequestHandlerAdapter:
-
RequestMappingHandlerAdapter:
-
会调用该方法 handleInternal() -
执行具体的方法invokeHandlerMethod mav = this.invokeHandlerMethod(request, response, handlerMethod); -
ServletInvocableHandlerMethod.class invocableMethod.invokeAndHandle(webRequest, mavContainer); -
InvocableHandlerMethod.class Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);-
获取请求参数 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); -
-
SimpleControllerHandlerAdapter
-
一般不用被初始化,只有上面三个 SimpleServletHandlerAdapter: servlet时使用

浙公网安备 33010602011771号