说在前面
本次主要介绍DispatcherServlet,关注”天河聊架构“更多精彩。
springmvc配置解析
进入方法org.springframework.web.bind.annotation.support.HandlerMethodInvoker#resolveHttpEntityRequest
private HttpEntity<?> resolveHttpEntityRequest(MethodParameter methodParam, NativeWebRequest webRequest) throws Exception { HttpInputMessage inputMessage = createHttpInputMessage(webRequest); Class<?> paramType = getHttpEntityType(methodParam); Object body = readWithMessageConverters(methodParam, inputMessage, paramType); return new HttpEntity<Object>(body, inputMessage.getHeaders()); }
返回方法org.springframework.web.bind.annotation.support.HandlerMethodInvoker#resolveRequestParam
private Object resolveRequestParam(String paramName, boolean required, String defaultValue, MethodParameter methodParam, NativeWebRequest webRequest, Object handlerForInitBinderCall) throws Exception { Class<?> paramType = methodParam.getParameterType(); if (Map.class.isAssignableFrom(paramType) && paramName.length() == 0) { return resolveRequestParamMap((Class<? extends Map<?, ?>>) paramType, webRequest); } if (paramName.length() == 0) { paramName = getRequiredParameterName(methodParam); } Object paramValue = null; // 解析上传文件的属性名 MultipartRequest multipartRequest = webRequest.getNativeRequest(MultipartRequest.class); if (multipartRequest != null) { List<MultipartFile> files = multipartRequest.getFiles(paramName); if (!files.isEmpty()) { paramValue = (files.size() == 1 ? files.get(0) : files); } } if (paramValue == null) { // 底层还是调用request.getParameterValues方法 String[] paramValues = webRequest.getParameterValues(paramName); if (paramValues != null) { paramValue = (paramValues.length == 1 ? paramValues[0] : paramValues); } } // 赋默认值 if (paramValue == null) { if (defaultValue != null) { paramValue = resolveDefaultValue(defaultValue); } // 如果是必填值就抛异常 else if (required) { raiseMissingParameterException(paramName, paramType); } paramValue = checkValue(paramName, paramValue, paramType); } // 创建属性绑定器 WebDataBinder binder = createBinder(webRequest, null, paramName); // 初始化参数绑定 -》 initBinder(handlerForInitBinderCall, paramName, binder, webRequest); return binder.convertIfNecessary(paramValue, paramType, methodParam); }
进入方法org.springframework.web.bind.annotation.support.HandlerMethodInvoker#initBinder
protected void initBinder(Object handler, String attrName, WebDataBinder binder, NativeWebRequest webRequest) throws Exception { if (this.bindingInitializer != null) { this.bindingInitializer.initBinder(binder, webRequest); } if (handler != null) { Set<Method> initBinderMethods = this.methodResolver.getInitBinderMethods(); if (!initBinderMethods.isEmpty()) { boolean debug = logger.isDebugEnabled(); for (Method initBinderMethod : initBinderMethods) { // 获取带有@InitBinder注解的方法 Method methodToInvoke = BridgeMethodResolver.findBridgedMethod(initBinderMethod); String[] targetNames = AnnotationUtils.findAnnotation(initBinderMethod, InitBinder.class).value(); if (targetNames.length == 0 || Arrays.asList(targetNames).contains(attrName)) { // 参数绑定 -》 Object[] initBinderArgs = resolveInitBinderArguments(handler, methodToInvoke, binder, webRequest); if (debug) { logger.debug("Invoking init-binder method: " + methodToInvoke); } ReflectionUtils.makeAccessible(methodToInvoke); // 执行方法-》 Object returnValue = methodToInvoke.invoke(handler, initBinderArgs); if (returnValue != null) { throw new IllegalStateException( "InitBinder methods must not have a return value: " + methodToInvoke); } } } } } }
返回方法org.springframework.web.bind.annotation.support.HandlerMethodInvoker#resolveRequestHeader
private Object resolveRequestHeader(String headerName, boolean required, String defaultValue, MethodParameter methodParam, NativeWebRequest webRequest, Object handlerForInitBinderCall) throws Exception { Class<?> paramType = methodParam.getParameterType(); if (Map.class.isAssignableFrom(paramType)) { return resolveRequestHeaderMap((Class<? extends Map<?, ?>>) paramType, webRequest); } if (headerName.length() == 0) { headerName = getRequiredParameterName(methodParam); } Object headerValue = null; String[] headerValues = webRequest.getHeaderValues(headerName); if (headerValues != null) { headerValue = (headerValues.length == 1 ? headerValues[0] : headerValues); } if (headerValue == null) { if (defaultValue != null) { headerValue = resolveDefaultValue(defaultValue); } else if (required) { raiseMissingHeaderException(headerName, paramType); } headerValue = checkValue(headerName, headerValue, paramType); } WebDataBinder binder = createBinder(webRequest, null, headerName); // 初始化绑定器-》 initBinder(handlerForInitBinderCall, headerName, binder, webRequest); return binder.convertIfNecessary(headerValue, paramType, methodParam); }
返回方法org.springframework.web.bind.annotation.support.HandlerMethodInvoker#readWithMessageConverters
private Object readWithMessageConverters(MethodParameter methodParam, HttpInputMessage inputMessage, Class<?> paramType) throws Exception { MediaType contentType = inputMessage.getHeaders().getContentType(); if (contentType == null) { StringBuilder builder = new StringBuilder(ClassUtils.getShortName(methodParam.getParameterType())); String paramName = methodParam.getParameterName(); if (paramName != null) { builder.append(' '); builder.append(paramName); } throw new HttpMediaTypeNotSupportedException( "Cannot extract parameter (" + builder.toString() + "): no Content-Type found"); } List<MediaType> allSupportedMediaTypes = new ArrayList<MediaType>(); if (this.messageConverters != null) { // 执行转换器 for (HttpMessageConverter<?> messageConverter : this.messageConverters) { allSupportedMediaTypes.addAll(messageConverter.getSupportedMediaTypes()); if (messageConverter.canRead(paramType, contentType)) { if (logger.isDebugEnabled()) { logger.debug("Reading [" + paramType.getName() + "] as \"" + contentType +"\" using [" + messageConverter + "]"); } return messageConverter.read((Class) paramType, inputMessage); } } } throw new HttpMediaTypeNotSupportedException(contentType, allSupportedMediaTypes); }
返回方法org.springframework.web.bind.annotation.support.HandlerMethodInvoker#resolveCookieValue(java.lang.String, boolean, java.lang.String, org.springframework.core.MethodParameter, org.springframework.web.context.request.NativeWebRequest, java.lang.Object)
private Object resolveCookieValue(String cookieName, boolean required, String defaultValue, MethodParameter methodParam, NativeWebRequest webRequest, Object handlerForInitBinderCall) throws Exception { Class<?> paramType = methodParam.getParameterType(); if (cookieName.length() == 0) { cookieName = getRequiredParameterName(methodParam); } Object cookieValue = resolveCookieValue(cookieName, paramType, webRequest); if (cookieValue == null) { if (defaultValue != null) { cookieValue = resolveDefaultValue(defaultValue); } else if (required) { raiseMissingCookieException(cookieName, paramType); } cookieValue = checkValue(cookieName, cookieValue, paramType); } WebDataBinder binder = createBinder(webRequest, null, cookieName); // 初始化绑定器-》 initBinder(handlerForInitBinderCall, cookieName, binder, webRequest); return binder.convertIfNecessary(cookieValue, paramType, methodParam); }
返回方法org.springframework.web.bind.annotation.support.HandlerMethodInvoker#resolvePathVariable(java.lang.String, org.springframework.core.MethodParameter, org.springframework.web.context.request.NativeWebRequest, java.lang.Object)
private Object resolvePathVariable(String pathVarName, MethodParameter methodParam, NativeWebRequest webRequest, Object handlerForInitBinderCall) throws Exception { Class<?> paramType = methodParam.getParameterType(); if (pathVarName.length() == 0) { pathVarName = getRequiredParameterName(methodParam); } String pathVarValue = resolvePathVariable(pathVarName, paramType, webRequest); WebDataBinder binder = createBinder(webRequest, null, pathVarName); // 初始化绑定器-》 initBinder(handlerForInitBinderCall, pathVarName, binder, webRequest); return binder.convertIfNecessary(pathVarValue, paramType, methodParam); }
返回方法org.springframework.web.bind.annotation.support.HandlerMethodInvoker#resolveModelAttribute
private WebDataBinder resolveModelAttribute(String attrName, MethodParameter methodParam, ExtendedModelMap implicitModel, NativeWebRequest webRequest, Object handler) throws Exception { // Bind request parameter onto object... String name = attrName; if ("".equals(name)) { name = Conventions.getVariableNameForParameter(methodParam); } Class<?> paramType = methodParam.getParameterType(); Object bindObject; if (implicitModel.containsKey(name)) { bindObject = implicitModel.get(name); } else if (this.methodResolver.isSessionAttribute(name, paramType)) { bindObject = this.sessionAttributeStore.retrieveAttribute(webRequest, name); if (bindObject == null) { raiseSessionRequiredException("Session attribute '" + name + "' required - not found in session"); } } else { bindObject = BeanUtils.instantiateClass(paramType); } WebDataBinder binder = createBinder(webRequest, bindObject, name); // 初始化绑定器-》 initBinder(handler, name, binder, webRequest); return binder; }
返回方法org.springframework.web.bind.annotation.support.HandlerMethodInvoker#doBind(org.springframework.web.bind.WebDataBinder, org.springframework.web.context.request.NativeWebRequest, boolean, java.lang.Object[], boolean)
private void doBind(WebDataBinder binder, NativeWebRequest webRequest, boolean validate, Object[] validationHints, boolean failOnErrors) throws Exception { doBind(binder, webRequest); if (validate) { // 执行参数验证 binder.validate(validationHints); } if (failOnErrors && binder.getBindingResult().hasErrors()) { throw new BindException(binder.getBindingResult()); } }
返回方法org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.ServletHandlerMethodInvoker#getModelAndView
public ModelAndView getModelAndView(Method handlerMethod, Class<?> handlerType, Object returnValue, ExtendedModelMap implicitModel, ServletWebRequest webRequest) throws Exception { // 解析@ResponseStatus注解 ResponseStatus responseStatus = AnnotatedElementUtils.findMergedAnnotation(handlerMethod, ResponseStatus.class); if (responseStatus != null) { HttpStatus statusCode = responseStatus.code(); String reason = responseStatus.reason(); if (!StringUtils.hasText(reason)) { webRequest.getResponse().setStatus(statusCode.value()); } else { webRequest.getResponse().sendError(statusCode.value(), reason); } // to be picked up by the RedirectView webRequest.getRequest().setAttribute(View.RESPONSE_STATUS_ATTRIBUTE, statusCode); this.responseArgumentUsed = true; } // Invoke custom resolvers if present... if (customModelAndViewResolvers != null) { for (ModelAndViewResolver mavResolver : customModelAndViewResolvers) { // 解析modelAndView-》 ModelAndView mav = mavResolver.resolveModelAndView( handlerMethod, handlerType, returnValue, implicitModel, webRequest); if (mav != ModelAndViewResolver.UNRESOLVED) { return mav; } } } if (returnValue instanceof HttpEntity) { // 解析HttpEntity响应 handleHttpEntityResponse((HttpEntity<?>) returnValue, webRequest); return null; } // 解析@ResponseBody注解 else if (AnnotationUtils.findAnnotation(handlerMethod, ResponseBody.class) != null) { // -》 handleResponseBody(returnValue, webRequest); return null; } else if (returnValue instanceof ModelAndView) { // 如果返回值是modelAndView创建并返回 ModelAndView mav = (ModelAndView) returnValue; mav.getModelMap().mergeAttributes(implicitModel); return mav; } else if (returnValue instanceof Model) { // 返回值是model return new ModelAndView().addAllObjects(implicitModel).addAllObjects(((Model) returnValue).asMap()); } else if (returnValue instanceof View) { // 返回值是view return new ModelAndView((View) returnValue).addAllObjects(implicitModel); } // 解析@ModelAttribute注解 else if (AnnotationUtils.findAnnotation(handlerMethod, ModelAttribute.class) != null) { // -》 addReturnValueAsModelAttribute(handlerMethod, handlerType, returnValue, implicitModel); return new ModelAndView().addAllObjects(implicitModel); } else if (returnValue instanceof Map) { // 返回值是map return new ModelAndView().addAllObjects(implicitModel).addAllObjects((Map<String, ?>) returnValue); } else if (returnValue instanceof String) { // 返回值是string return new ModelAndView((String) returnValue).addAllObjects(implicitModel); } else if (returnValue == null) { // 没有返回值 // Either returned null or was 'void' return. if (this.responseArgumentUsed || webRequest.isNotModified()) { return null; } else { // Assuming view name translation... return new ModelAndView().addAllObjects(implicitModel); } } else if (!BeanUtils.isSimpleProperty(returnValue.getClass())) { // Assume a single model attribute... addReturnValueAsModelAttribute(handlerMethod, handlerType, returnValue, implicitModel); return new ModelAndView().addAllObjects(implicitModel); } else { throw new IllegalArgumentException("Invalid handler method return value: " + returnValue); } }
进入方法org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.ServletHandlerMethodInvoker#handleHttpEntityResponse
private void handleHttpEntityResponse(HttpEntity<?> responseEntity, ServletWebRequest webRequest) throws Exception { if (responseEntity == null) { return; } HttpInputMessage inputMessage = createHttpInputMessage(webRequest); HttpOutputMessage outputMessage = createHttpOutputMessage(webRequest); if (responseEntity instanceof ResponseEntity && outputMessage instanceof ServerHttpResponse) { ((ServerHttpResponse) outputMessage).setStatusCode(((ResponseEntity<?>) responseEntity).getStatusCode()); } HttpHeaders entityHeaders = responseEntity.getHeaders(); if (!entityHeaders.isEmpty()) { outputMessage.getHeaders().putAll(entityHeaders); } Object body = responseEntity.getBody(); if (body != null) { // 调用转换器-》 writeWithMessageConverters(body, inputMessage, outputMessage); } else { // flush headers outputMessage.getBody(); } }
返回方法org.springframework.web.servlet.DispatcherServlet#applyDefaultViewName
private void applyDefaultViewName(HttpServletRequest request, ModelAndView mv) throws Exception { if (mv != null && !mv.hasView()) { mv.setViewName(getDefaultViewName(request)); } }
进入方法org.springframework.web.servlet.DispatcherServlet#getDefaultViewName
protected String getDefaultViewName(HttpServletRequest request) throws Exception { return this.viewNameTranslator.getViewName(request); }
返回方法org.springframework.web.servlet.HandlerExecutionChain#applyPostHandle
void applyPostHandle(HttpServletRequest request, HttpServletResponse response, ModelAndView mv) throws Exception { HandlerInterceptor[] interceptors = getInterceptors(); if (!ObjectUtils.isEmpty(interceptors)) { for (int i = interceptors.length - 1; i >= 0; i--) { HandlerInterceptor interceptor = interceptors[i]; // 执行业务handler拦截器后置方法 interceptor.postHandle(request, response, this.handler, mv); } } }
进入方法org.springframework.web.servlet.HandlerExecutionChain#getInterceptors
public HandlerInterceptor[] getInterceptors() { if (this.interceptors == null && this.interceptorList != null) { this.interceptors = this.interceptorList.toArray(new HandlerInterceptor[this.interceptorList.size()]); } return this.interceptors; }
进入方法org.springframework.web.servlet.DispatcherServlet#processDispatchResult
private void processDispatchResult(HttpServletRequest request, HttpServletResponse response, HandlerExecutionChain mappedHandler, ModelAndView mv, Exception exception) throws Exception { boolean errorView = false; if (exception != null) { if (exception instanceof ModelAndViewDefiningException) { logger.debug("ModelAndViewDefiningException encountered", exception); mv = ((ModelAndViewDefiningException) exception).getModelAndView(); } else { Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null); // 用异常解析器处理异常-》 mv = processHandlerException(request, response, handler, exception); errorView = (mv != null); } } // Did the handler return a view to render? if (mv != null && !mv.wasCleared()) { render(mv, request, response); if (errorView) { // 清空绑定 -》 WebUtils.clearErrorRequestAttributes(request); } } else { if (logger.isDebugEnabled()) { logger.debug("Null ModelAndView returned to DispatcherServlet with name '" + getServletName() + "': assuming HandlerAdapter completed request handling"); } } // 异步请求,同步直接返回 if (WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) { // Concurrent handling started during a forward return; } if (mappedHandler != null) { // 执行拦截器的处理完成事件 -》 mappedHandler.triggerAfterCompletion(request, response, null); } }
进入方法org.springframework.web.servlet.DispatcherServlet#processHandlerException
protected ModelAndView processHandlerException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // Check registered HandlerExceptionResolvers... ModelAndView exMv = null; for (HandlerExceptionResolver handlerExceptionResolver : this.handlerExceptionResolvers) { exMv = handlerExceptionResolver.resolveException(request, response, handler, ex); if (exMv != null) { break; } } if (exMv != null) { if (exMv.isEmpty()) { request.setAttribute(EXCEPTION_ATTRIBUTE, ex); return null; } // We might still need view name translation for a plain error model... if (!exMv.hasView()) { // 设置默认视图 exMv.setViewName(getDefaultViewName(request)); } if (logger.isDebugEnabled()) { logger.debug("Handler execution resulted in exception - forwarding to resolved error view: " + exMv, ex); } // 绑定配置-》 WebUtils.exposeErrorRequestAttributes(request, ex, getServletName()); return exMv; } throw ex; }
进入方法org.springframework.web.util.WebUtils#exposeErrorRequestAttributes
public static void exposeErrorRequestAttributes(HttpServletRequest request, Throwable ex, String servletName) { exposeRequestAttributeIfNotPresent(request, ERROR_STATUS_CODE_ATTRIBUTE, HttpServletResponse.SC_OK); exposeRequestAttributeIfNotPresent(request, ERROR_EXCEPTION_TYPE_ATTRIBUTE, ex.getClass()); exposeRequestAttributeIfNotPresent(request, ERROR_MESSAGE_ATTRIBUTE, ex.getMessage()); exposeRequestAttributeIfNotPresent(request, ERROR_EXCEPTION_ATTRIBUTE, ex); exposeRequestAttributeIfNotPresent(request, ERROR_REQUEST_URI_ATTRIBUTE, request.getRequestURI()); exposeRequestAttributeIfNotPresent(request, ERROR_SERVLET_NAME_ATTRIBUTE, servletName); }
返回方法org.springframework.web.util.WebUtils#clearErrorRequestAttributes
public static void clearErrorRequestAttributes(HttpServletRequest request) { request.removeAttribute(ERROR_STATUS_CODE_ATTRIBUTE); request.removeAttribute(ERROR_EXCEPTION_TYPE_ATTRIBUTE); request.removeAttribute(ERROR_MESSAGE_ATTRIBUTE); request.removeAttribute(ERROR_EXCEPTION_ATTRIBUTE); request.removeAttribute(ERROR_REQUEST_URI_ATTRIBUTE); request.removeAttribute(ERROR_SERVLET_NAME_ATTRIBUTE); }
返回方法org.springframework.web.servlet.HandlerExecutionChain#triggerAfterCompletion
void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, Exception ex) throws Exception { // 获取拦截器 -》 HandlerInterceptor[] interceptors = getInterceptors(); if (!ObjectUtils.isEmpty(interceptors)) { for (int i = this.interceptorIndex; i >= 0; i--) { HandlerInterceptor interceptor = interceptors[i]; try { // 执行拦截器的完成事件 interceptor.afterCompletion(request, response, this.handler, ex); } catch (Throwable ex2) { logger.error("HandlerInterceptor.afterCompletion threw exception", ex2); } } } }
进入方法org.springframework.web.servlet.HandlerExecutionChain#getInterceptors
public HandlerInterceptor[] getInterceptors() { if (this.interceptors == null && this.interceptorList != null) { this.interceptors = this.interceptorList.toArray(new HandlerInterceptor[this.interceptorList.size()]); } return this.interceptors; }
返回方法org.springframework.web.servlet.DispatcherServlet#triggerAfterCompletion
private void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, HandlerExecutionChain mappedHandler, Exception ex) throws Exception { if (mappedHandler != null) { mappedHandler.triggerAfterCompletion(request, response, ex); } throw ex; }
进入方法org.springframework.web.servlet.HandlerExecutionChain#triggerAfterCompletion
void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, Exception ex) throws Exception { // 获取拦截器 -》 HandlerInterceptor[] interceptors = getInterceptors(); if (!ObjectUtils.isEmpty(interceptors)) { for (int i = this.interceptorIndex; i >= 0; i--) { HandlerInterceptor interceptor = interceptors[i]; try { // 执行拦截器的完成事件 interceptor.afterCompletion(request, response, this.handler, ex); } catch (Throwable ex2) { logger.error("HandlerInterceptor.afterCompletion threw exception", ex2); } } } }
返回方法org.springframework.web.servlet.HandlerExecutionChain#applyAfterConcurrentHandlingStarted
void applyAfterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response) { HandlerInterceptor[] interceptors = getInterceptors(); if (!ObjectUtils.isEmpty(interceptors)) { for (int i = interceptors.length - 1; i >= 0; i--) { if (interceptors[i] instanceof AsyncHandlerInterceptor) { try { AsyncHandlerInterceptor asyncInterceptor = (AsyncHandlerInterceptor) interceptors[i]; asyncInterceptor.afterConcurrentHandlingStarted(request, response, this.handler); } catch (Throwable ex) { logger.error("Interceptor [" + interceptors[i] + "] failed in afterConcurrentHandlingStarted", ex); } } } } }
返回方法org.springframework.web.servlet.DispatcherServlet#restoreAttributesAfterInclude
private void restoreAttributesAfterInclude(HttpServletRequest request, Map<?,?> attributesSnapshot) { // Need to copy into separate Collection here, to avoid side effects // on the Enumeration when removing attributes. Set<String> attrsToCheck = new HashSet<String>(); Enumeration<?> attrNames = request.getAttributeNames(); while (attrNames.hasMoreElements()) { String attrName = (String) attrNames.nextElement(); if (this.cleanupAfterInclude || attrName.startsWith(DEFAULT_STRATEGIES_PREFIX)) { attrsToCheck.add(attrName); } } // Add attributes that may have been removed attrsToCheck.addAll((Set<String>) attributesSnapshot.keySet()); // Iterate over the attributes to check, restoring the original value // or removing the attribute, respectively, if appropriate. for (String attrName : attrsToCheck) { Object attrValue = attributesSnapshot.get(attrName); if (attrValue == null){ request.removeAttribute(attrName); } else if (attrValue != request.getAttribute(attrName)) { request.setAttribute(attrName, attrValue); } } }
往上返回到这个方法org.springframework.web.servlet.FrameworkServlet#service
说到最后
本次源码解析仅代表个人观点,仅供参考。