WebMvcAutoConfiguration SpringMvc自动注入类
//当前为配置类@Configuration(proxyBeanMethods = false)//当前应用必须为web应用@ConditionalOnWebApplication(type = Type.SERVLET)//必须存在 Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class//主要的入口为DispatcherServlet.class@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })//确保springbean中未注册多个WebMvcConfigurationSupport.class@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)//优先级@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class,ValidationAutoConfiguration.class })public class WebMvcAutoConfiguration {
DispatcherServlet
//DispatcherServlet 继承 FrameworkServlet //而FrameworkServlet 继承httpServletBean//继承httpServletBean => httpServlet,所以DispatcherServlet 有 Servlet// 原生的方法 doGet doPostpublic class DispatcherServlet extends FrameworkServlet {
DispatcherServlet 继承关系

FrameworkServlet重写doGet、doPost等方法,这里就是我们在请求的时候进行转发的地方,当我们进行GET、POST等方法的时候会进入调用 processRequest(request, response);

processRequest(request, response),调用此方法后,加载对应的属性,调用doService(request, response)方法进行处理逻辑
protected final void processRequest(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException { long startTime = System.currentTimeMillis(); Throwable failureCause = null;LocaleContext previousLocaleContext = LocaleContextHolder.getLocaleContext();LocaleContext localeContext = buildLocaleContext(request);RequestAttributes previousAttributes = RequestContextHolder.getRequestAttributes();ServletRequestAttributes requestAttributes = buildRequestAttributes(request, response, previousAttributes);WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);asyncManager.registerCallableInterceptor(FrameworkServlet.class.getName(), new RequestBindingInterceptor());initContextHolders(request, localeContext, requestAttributes);try { //主要的执行方法doService(request, response);}catch (ServletException | IOException ex) {failureCause = ex;throw ex;}catch (Throwable ex) {failureCause = ex;throw new NestedServletException("Request processing failed", ex);}finally {resetContextHolders(request, previousLocaleContext, previousAttributes);if (requestAttributes != null) {requestAttributes.requestCompleted();}logResult(request, response, failureCause, asyncManager);publishRequestHandledEvent(request, response, startTime, failureCause);}}
doService(HttpServletRequest request, HttpServletResponse response) 进入到当前方法中,调用最终执行方法 doDispatch(request, response);
//方法存在于 DispatcherServlet.class 中@Overrideprotected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception { logRequest(request); // Keep a snapshot of the request attributes in case of an include, // to be able to restore the original attributes after the include. Map attributesSnapshot = null; if (WebUtils.isIncludeRequest(request)) { attributesSnapshot = new HashMap(); Enumeration attrNames = request.getAttributeNames(); while (attrNames.hasMoreElements()) { String attrName = (String) attrNames.nextElement(); if (this.cleanupAfterInclude || attrName.startsWith(DEFAULT_STRATEGIES_PREFIX)) { attributesSnapshot.put(attrName, request.getAttribute(attrName)); } } } // Make framework objects available to handlers and view objects. request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, getWebApplicationContext()); request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver); request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver); request.setAttribute(THEME_SOURCE_ATTRIBUTE, getThemeSource()); if (this.flashMapManager != null) { FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate(request, response); if (inputFlashMap != null) { request.setAttribute(INPUT_FLASH_MAP_ATTRIBUTE, Collections.unmodifiableMap(inputFlashMap)); } request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap()); request.setAttribute(FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager); } RequestPath previousRequestPath = null; if (this.parseRequestPath) { previousRequestPath = (RequestPath) request.getAttribute(ServletRequestPathUtils.PATH_ATTRIBUTE); ServletRequestPathUtils.parseAndCache(request); } try { //最终执行逻辑方法 doDispatch(request, response); } finally { if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) { // Restore the original attribute snapshot, in case of an include. if (attributesSnapshot != null) { restoreAttributesAfterInclude(request, attributesSnapshot); } } if (this.parseRequestPath) { ServletRequestPathUtils.setParsedRequestPath(previousRequestPath, request); } }}
doDispatch(request, response); 获取控制器,获取控制器对应的适配器,控制器执行解析数据生成modelAndView视图
checkMultipart(request):检查是否存在文件上传
getHandler(processedRequest):获取Handel 控制器
getHandlerAdapter(mappedHandler.getHandler()):获取控制器适配器
ha.handle(processedRequest, response,
mappedHandler.getHandler()):执行控制器获取modelAndView
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { HttpServletRequest processedRequest = request; HandlerExecutionChain mappedHandler = null; boolean multipartRequestParsed = false; WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request); try { ModelAndView mv = null; Exception dispatchException = null; try { //检查是否存在文件上传 processedRequest = checkMultipart(request); multipartRequestParsed = (processedRequest != request); // Determine handler for the current request. //获取对应的控制器handel mappedHandler = getHandler(processedRequest); if (mappedHandler == null) { noHandlerFound(processedRequest, response); return; } // Determine handler adapter for the current request. //获取Handel的适配器Adapter HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); // Process last-modified header, if supported by the handler. 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; } // Actually invoke the handler. // 执行控制器方法,返回modelAndView mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); if (asyncManager.isConcurrentHandlingStarted()) { return; } applyDefaultViewName(processedRequest, mv); // 执行中通知 mappedHandler.applyPostHandle(processedRequest, response, mv); } catch (Exception ex) { dispatchException = ex; } catch (Throwable err) { // As of 4.3, we're processing Errors thrown from handler methods as well, // making them available for @ExceptionHandler methods and other scenarios. dispatchException = new NestedServletException("Handler dispatch failed", err); } //业务完成通知 processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException); } catch (Exception ex) { triggerAfterCompletion(processedRequest, response, mappedHandler, ex); } catch (Throwable err) { triggerAfterCompletion(processedRequest, response, mappedHandler, new NestedServletException("Handler processing failed", err)); } finally { if (asyncManager.isConcurrentHandlingStarted()) { // Instead of postHandle and afterCompletion if (mappedHandler != null) { mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response); } } else { // Clean up any resources used by a multipart request. if (multipartRequestParsed) { cleanupMultipart(processedRequest); } } }}
getHandler(processedRequest) 获取控制器,循环遍历获取到对应的handel控制器
@Nullableprotected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {if (this.handlerMappings != null) {for (HandlerMapping mapping : this.handlerMappings) {HandlerExecutionChain handler = mapping.getHandler(request);if (handler != null) {return handler;}}}return null;}
handlerMappings 获取对应的handel

我们以requestMappingHandelMapping为例,当前控制器中存放的是我们注解@RequestMapping 所标记的地址,如下图,我当前controller有两个get方法,分别是user 和 testLock

我们可以看内部的实现类是我们创建类且下面对应的方法

getHandlerAdapter(Object handler):this.handlerAdapters 能过 adapter.supports(handler) 获取适配handel 的 adapter 适配器
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {if (this.handlerAdapters != null) { //循环获取匹配handel对应的adapterfor (HandlerAdapter adapter : this.handlerAdapters) {if (adapter.supports(handler)) {return adapter;}}}throw new ServletException("No adapter for handler [" + handler +"]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");}
ha.handle(processedRequest, response, mappedHandler.getHandler()):
@Override@Nullable//调用的为 HttpRequestHandlerAdapter => handlepublic ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//调用最终执行方法 ((HttpRequestHandler) handler).handleRequest(request, response); return null;}
((HttpRequestHandler) handler).handleRequest(request, response) 执行方法
@Override//调用的为 RequestMappingHandlerAdapter => handleInternalprotected 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 necessary mav = 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;}
invokeHandlerMethod(request, response, handlerMethod)
@Nullableprotected 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); //加载数据解析器 如@RequestParam等数据解析注解 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(); }}
this.argumentResolvers 参数解析器,如requestParamMethodArgumentResolver解析的是注解为@RequestParam相关参数 PathVariableMethodArgumentResolver解析的是注解为@PathVariable 参数,其他依次类推

this.returnValueHandlers 返回值处理器,如reqeustResponseBodyMethodProcessor解析的是注解为@ResponseBody返回JSON数据格式,其他依次类推

invocableMethod.invokeAndHandle(webRequest, mavContainer); 数据获取方法
//ServletInvocableHandlerMethod => invokeAndHandlepublic void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer,Object... providedArgs) throws Exception { //获取返回值 Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs); setResponseStatus(webRequest); if (returnValue == null) { if (isRequestNotModified(webRequest) || getResponseStatus() != null || mavContainer.isRequestHandled()) { disableContentCachingIfNecessary(webRequest); mavContainer.setRequestHandled(true); return; } } else if (StringUtils.hasText(getResponseStatusReason())) { mavContainer.setRequestHandled(true); return; } mavContainer.setRequestHandled(false); Assert.state(this.returnValueHandlers != null, "No return value handlers"); try { this.returnValueHandlers.handleReturnValue( returnValue, getReturnValueType(returnValue), mavContainer, webRequest); } catch (Exception ex) { if (logger.isTraceEnabled()) { logger.trace(formatErrorForReturnValue(returnValue), ex); } throw ex; }}
invokeForRequest(webRequest, mavContainer, providedArgs); 获取接口返回值
@Nullablepublic Object invokeForRequest(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,Object... providedArgs) throws Exception { //实际执行方法Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);if (logger.isTraceEnabled()) {logger.trace("Arguments: " + Arrays.toString(args));}return doInvoke(args);}
getMethodArgumentValues(request, mavContainer, providedArgs); 数据获取
//HandlerMethod => getMethodArgumentValuesprotected Object[] getMethodArgumentValues(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception { //获取所以参数方法 类型和注解等信息 MethodParameter[] parameters = getMethodParameters(); if (ObjectUtils.isEmpty(parameters)) { return EMPTY_ARGS; } // 遍历参数方法信息,获取注解对应参数值 Object[] args = new Object[parameters.length]; for (int i = 0; i < parameters.length; i++) { //获取当前参数详细 MethodParameter parameter = parameters[i]; parameter.initParameterNameDiscovery(this.parameterNameDiscoverer); //找到提供参数 args[i] = findProvidedArgument(parameter, providedArgs); if (args[i] != null) { continue; } if (!this.resolvers.supportsParameter(parameter)) { throw new IllegalStateException(formatArgumentError(parameter, "No suitable resolver")); } try { //获取参数解析器 args[i] = this.resolvers.resolveArgument(parameter, mavContainer, request, this.dataBinderFactory); } catch (Exception ex) { // Leave stack trace for later, exception may actually be resolved and handled... if (logger.isDebugEnabled()) { String exMsg = ex.getMessage(); if (exMsg != null && !exMsg.contains(parameter.getExecutable().toGenericString())) { logger.debug(formatArgumentError(parameter, exMsg)); } } throw ex; } } return args;}
所有参数对象详细信息

this.resolvers.resolveArgument(parameter, mavContainer, request, this.dataBinderFactory); 获取参数解析器
@Override@Nullablepublic Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception { //获取控制器方法的参数解析器HandlerMethodArgumentResolver resolver = getArgumentResolver(parameter);if (resolver == null) {throw new IllegalArgumentException("Unsupported parameter type [" +parameter.getParameterType().getName() + "]. supportsParameter should be called first.");}return resolver.resolveArgument(parameter, mavContainer, webRequest, binderFactory);}
getArgumentResolver(parameter);
@Nullable//HandlerMethodArgumentResolverComposite => getArgumentResolverprivate HandlerMethodArgumentResolver getArgumentResolver(MethodParameter parameter) { //参数方法对象获取对应的参数解析器 -》 缓存获取 HandlerMethodArgumentResolver result = this.argumentResolverCache.get(parameter); if (result == null) { //缓存中不存在时,遍历获取当前参数解析器 for (HandlerMethodArgumentResolver resolver : this.argumentResolvers) { if (resolver.supportsParameter(parameter)) { result = resolver; this.argumentResolverCache.put(parameter, result); break; } } } return result;}

就此整个请求及参数获取相关内容就是这些,如有错误理解地方,望各位大佬指导指导。
谢谢观看!!!!!
在线等待指导!!!!
天天排行榜