自主建站网站平台/个人网站制作模板主页
文章目录
- 0.前记
- 1.HandlerMapping和HandlerAdapter的交互
- 2.RequestMappingHandlerAdapter 如何工作
- 3.RequestMappingHandlerAdapter 如何执行目标方法的
0.前记
根据之前的文章, 在DispatcherServlet初始化的时候会发生HandlerAdapter的初始化
DispatcherServlet#doDispatch()
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {HttpServletRequest processedRequest = request;HandlerExecutionChain mappedHandler = null;boolean multipartRequestParsed = false;WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);try {try {ModelAndView mv = null;Object dispatchException = null;try {processedRequest = this.checkMultipart(request);multipartRequestParsed = processedRequest != request;mappedHandler = this.getHandler(processedRequest);if (mappedHandler == null) {this.noHandlerFound(processedRequest, response);return;}HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());String method = request.getMethod();boolean isGet = HttpMethod.GET.matches(method);if (isGet || HttpMethod.HEAD.matches(method)) {long lastModified = ha.getLastModified(request, mappedHandler.getHandler());if ((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) {return;}}if (!mappedHandler.applyPreHandle(processedRequest, response)) {return;}mv = ha.handle(processedRequest, response, mappedHandler.getHandler());if (asyncManager.isConcurrentHandlingStarted()) {return;}this.applyDefaultViewName(processedRequest, mv);mappedHandler.applyPostHandle(processedRequest, response, mv);} catch (Exception var20) {dispatchException = var20;} catch (Throwable var21) {dispatchException = new NestedServletException("Handler dispatch failed", var21);}this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException);} catch (Exception var22) {this.triggerAfterCompletion(processedRequest, response, mappedHandler, var22);} catch (Throwable var23) {this.triggerAfterCompletion(processedRequest, response, mappedHandler, new NestedServletException("Handler processing failed", var23));}} finally {if (asyncManager.isConcurrentHandlingStarted()) {if (mappedHandler != null) {mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);}} else if (multipartRequestParsed) {this.cleanupMultipart(processedRequest);}}}
1.HandlerMapping和HandlerAdapter的交互
生成的默认的HandlerAdapter
- HttpRequestHandlerAdapter
- SimpleControllerHandlerAdapter
- RequestMappingHandlerAdapter
- HandlerFunctionAdapter
这里通过适配器模式+策略模式匹配对应的HandlerMapping
supports 为策略模式, handler 为适配器模式
通过策略模式, 不同的HandlerAdapter 进行工作。
- 比如:HttpRequestHandlerAdapter 判断是否是HttpRequestHandler接口
@Controller("/helloReq")
public class Controller02 implements HttpRequestHandler {@Overridepublic void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}
}
- SimpleControllerHandlerAdapter 判断是否是Controller 接口
@org.springframework.stereotype.Controller("/helloSimple")
public class Controller01 implements Controller {@Overridepublic ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {return null;}
}
- RequestMappingHandlerAdapter
判断是否符合HandlerMethod接口
这种适配器比较麻烦 需要和HandlerMethod适配, 和参数和返回值和注解的处理关系。
标注解的都是这个适配器处理的
2.RequestMappingHandlerAdapter 如何工作
适配过程: 将request, response, handler连接起来处理, 返回ModelAndView
HandlerAdapter#handler()
DispatcherServlet#doDipspatch()
- 前置拦截
- 目标方法执行
- 后置拦截
ha.handler -> RequestMappingHandlerAdapter#handleInternal()
@Overrideprotected ModelAndView handleInternal(HttpServletRequest request,HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {ModelAndView mav;checkRequest(request);// Execute invokeHandlerMethod in synchronized block if required.if (this.synchronizeOnSession) {HttpSession session = request.getSession(false);if (session != null) {Object mutex = WebUtils.getSessionMutex(session);synchronized (mutex) {mav = invokeHandlerMethod(request, response, handlerMethod);}}else {// No HttpSession available -> no mutex necessarymav = invokeHandlerMethod(request, response, handlerMethod);}}else {// No synchronization on session demanded at all...mav = invokeHandlerMethod(request, response, handlerMethod);}if (!response.containsHeader(HEADER_CACHE_CONTROL)) {if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers);}else {prepareResponse(response);}}return mav;}
3.RequestMappingHandlerAdapter 如何执行目标方法的
invokeHandlerMethod(request, response, handlerMethod);
protected ModelAndView invokeHandlerMethod(HttpServletRequest request,HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {ServletWebRequest webRequest = new ServletWebRequest(request, response);try {WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);if (this.argumentResolvers != null) {invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);}if (this.returnValueHandlers != null) {invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);}invocableMethod.setDataBinderFactory(binderFactory);invocableMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer);ModelAndViewContainer mavContainer = new ModelAndViewContainer();mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request));modelFactory.initModel(webRequest, mavContainer, invocableMethod);mavContainer.setIgnoreDefaultModelOnRedirect(this.ignoreDefaultModelOnRedirect);AsyncWebRequest asyncWebRequest = WebAsyncUtils.createAsyncWebRequest(request, response);asyncWebRequest.setTimeout(this.asyncRequestTimeout);WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);asyncManager.setTaskExecutor(this.taskExecutor);asyncManager.setAsyncWebRequest(asyncWebRequest);asyncManager.registerCallableInterceptors(this.callableInterceptors);asyncManager.registerDeferredResultInterceptors(this.deferredResultInterceptors);if (asyncManager.hasConcurrentResult()) {Object result = asyncManager.getConcurrentResult();mavContainer = (ModelAndViewContainer) asyncManager.getConcurrentResultContext()[0];asyncManager.clearConcurrentResult();LogFormatUtils.traceDebug(logger, traceOn -> {String formatted = LogFormatUtils.formatValue(result, !traceOn);return "Resume with async result [" + formatted + "]";});invocableMethod = invocableMethod.wrapConcurrentResult(result);}invocableMethod.invokeAndHandle(webRequest, mavContainer);if (asyncManager.isConcurrentHandlingStarted()) {return null;}return getModelAndView(mavContainer, modelFactory, webRequest);}finally {webRequest.requestCompleted();}}
- 建立一个空的
DataBinder
工厂, 建立一个存放处理器方法和DataBinder
工厂的模型工厂
这里注意一些, Model 相当于数据, View相当于视图 - 封装
HandlerMethod
为ServletInvocableHandlerMethod
, 装饰器模式, 提供了参数解析器和返回值解析器 ModelAndViewContainer
是模型和视图的容器, 把处理过程中产生和模型与视图有关的数据先放这里
在请求过程中共享的数据的ModelAndView
invocableMethod.invokeAndHandle(webRequest, mavContainer);
执行目标方法, 数据存放在mavContainer
getModelAndView(mavContainer, modelFactory, webRequest);
提取到ModelAndView
数据并返回。可以去View视图展示