說在前面java
本次主要介紹DispatcherServlet,更多精彩請關注」天河聊架構「微信公衆號。web
springmvc配置解析spring
找到這個方法org.springframework.web.servlet.handler.AbstractHandlerMapping#getHandlerExecutionChain跨域
protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) { HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ? (HandlerExecutionChain) handler : new HandlerExecutionChain(handler)); // 找到請求路徑 String lookupPath = this.urlPathHelper.getLookupPathForRequest(request); // 執行攔截器處理 for (HandlerInterceptor interceptor : this.adaptedInterceptors) { if (interceptor instanceof MappedInterceptor) { MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor; if (mappedInterceptor.matches(lookupPath, this.pathMatcher)) { chain.addInterceptor(mappedInterceptor.getInterceptor()); } } else { chain.addInterceptor(interceptor); } } return chain; }
往上返回到這個方法org.springframework.web.cors.UrlBasedCorsConfigurationSource#getCorsConfiguration緩存
@Override public CorsConfiguration getCorsConfiguration(HttpServletRequest request) { // 獲取請求路徑 -》 String lookupPath = this.urlPathHelper.getLookupPathForRequest(request); for (Map.Entry<String, CorsConfiguration> entry : this.corsConfigurations.entrySet()) { if (this.pathMatcher.match(entry.getKey(), lookupPath)) { return entry.getValue(); } } return null; }
進入到這個方法org.springframework.web.util.UrlPathHelper#getLookupPathForRequest微信
public String getLookupPathForRequest(HttpServletRequest request) { // Always use full path within current servlet context? 老是在當前servlet上下文中使用完整路徑? -》 if (this.alwaysUseFullPath) { return getPathWithinApplication(request); } // Else, use path within current servlet mapping if applicable 不然,在當前servlet映射中使用path(若是適用) String rest = getPathWithinServletMapping(request); if (!"".equals(rest)) { return rest; } else { return getPathWithinApplication(request); } }
這裏前面介紹過了。session
往上返回到這個方法org.springframework.web.servlet.handler.AbstractHandlerMapping#getCorsConfiguration架構
protected CorsConfiguration getCorsConfiguration(Object handler, HttpServletRequest request) { Object resolvedHandler = handler; if (handler instanceof HandlerExecutionChain) { resolvedHandler = ((HandlerExecutionChain) handler).getHandler(); } if (resolvedHandler instanceof CorsConfigurationSource) { // 獲取跨域配置 -》 return ((CorsConfigurationSource) resolvedHandler).getCorsConfiguration(request); } return null; }
進入到這個方法org.springframework.web.servlet.handler.HandlerMappingIntrospector#getCorsConfigurationmvc
@Override public CorsConfiguration getCorsConfiguration(HttpServletRequest request) { Assert.notNull(this.handlerMappings, "Handler mappings not initialized"); HttpServletRequest wrapper = new RequestAttributeChangeIgnoringWrapper(request); for (HandlerMapping handlerMapping : this.handlerMappings) { HandlerExecutionChain handler = null; try { // 獲取handler -》 handler = handlerMapping.getHandler(wrapper); } catch (Exception ex) { // Ignore } if (handler == null) { continue; } if (handler.getInterceptors() != null) { for (HandlerInterceptor interceptor : handler.getInterceptors()) { if (interceptor instanceof CorsConfigurationSource) { return ((CorsConfigurationSource) interceptor).getCorsConfiguration(wrapper); } } } if (handler.getHandler() instanceof CorsConfigurationSource) { return ((CorsConfigurationSource) handler.getHandler()).getCorsConfiguration(wrapper); } } return null; }
往上返回到這個方法org.springframework.web.servlet.handler.AbstractHandlerMapping#getCorsHandlerExecutionChainapp
protected HandlerExecutionChain getCorsHandlerExecutionChain(HttpServletRequest request, HandlerExecutionChain chain, CorsConfiguration config) { // -》 if (CorsUtils.isPreFlightRequest(request)) { // 獲取執行鏈上的攔截器 HandlerInterceptor[] interceptors = chain.getInterceptors(); chain = new HandlerExecutionChain(new PreFlightHandler(config), interceptors); } else { // 添加CorsInterceptor chain.addInterceptor(new CorsInterceptor(config)); } return chain; }
進入到這個方法org.springframework.web.cors.CorsUtils#isPreFlightRequest
public static boolean isPreFlightRequest(HttpServletRequest request) { return (isCorsRequest(request) && HttpMethod.OPTIONS.matches(request.getMethod()) && request.getHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD) != null); }
往上返回到這個方法org.springframework.web.servlet.DispatcherServlet#noHandlerFound
protected void noHandlerFound(HttpServletRequest request, HttpServletResponse response) throws Exception { if (pageNotFoundLogger.isWarnEnabled()) { pageNotFoundLogger.warn("No mapping found for HTTP request with URI [" + getRequestUri(request) + "] in DispatcherServlet with name '" + getServletName() + "'"); } if (this.throwExceptionIfNoHandlerFound) { throw new NoHandlerFoundException(request.getMethod(), getRequestUri(request), new ServletServerHttpRequest(request).getHeaders()); } else { response.sendError(HttpServletResponse.SC_NOT_FOUND); } }
往上返回到這個方法org.springframework.web.servlet.DispatcherServlet#getHandlerAdapter
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException { for (HandlerAdapter ha : this.handlerAdapters) { if (logger.isTraceEnabled()) { logger.trace("Testing handler adapter [" + ha + "]"); } if (ha.supports(handler)) { return ha; } } throw new ServletException("No adapter for handler [" + handler + "]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler"); }
往上返回到這個方法org.springframework.web.servlet.HandlerExecutionChain#applyPreHandle
boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception { // 獲取hander的攔截器 -》 HandlerInterceptor[] interceptors = getInterceptors(); if (!ObjectUtils.isEmpty(interceptors)) { for (int i = 0; i < interceptors.length; i++) { HandlerInterceptor interceptor = interceptors[i]; // 執行攔截器的前置處理方法 if (!interceptor.preHandle(request, response, this.handler)) { // 出發執行完成事件 -》 triggerAfterCompletion(request, response, null); return false; } this.interceptorIndex = i; } } return true; }
進入到這個方法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.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.mvc.method.AbstractHandlerMethodAdapter#handle默認實現方法執行
@Override public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return handleInternal(request, response, (HandlerMethod) handler); }
進入到這個方法org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#handleInternal
@Override protected 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) { // 執行handler的業務方法 @RequestMapping標準的方法 -》 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; }
進入到這個方法org.springframework.web.servlet.support.WebContentGenerator#checkRequest
protected final void checkRequest(HttpServletRequest request) throws ServletException { // Check whether we should support the request method. String method = request.getMethod(); // 請求方法不支持 if (this.supportedMethods != null && !this.supportedMethods.contains(method)) { throw new HttpRequestMethodNotSupportedException(method, this.supportedMethods); } // Check whether a session is required. 檢查session if (this.requireSession && request.getSession(false) == null) { throw new HttpSessionRequiredException("Pre-existing session required but none found"); } }
往上返回到這個方法org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#invokeHandlerMethod
protected ModelAndView invokeHandlerMethod(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception { ServletWebRequest webRequest = new ServletWebRequest(request, response); try { // 根據業務handler方法獲取web數據綁定工廠 -》 WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod); // 獲取ModelFactory -》 ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory); ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod); // 設置執行方法的參數解析器 invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers); // 設置執行方法的返回值解析器 invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers); invocableMethod.setDataBinderFactory(binderFactory); invocableMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer); // 建立modelAndView容器 ModelAndViewContainer mavContainer = new ModelAndViewContainer(); mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request)); // 初始化model -》 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(); if (logger.isDebugEnabled()) { logger.debug("Found concurrent result value [" + result + "]"); } invocableMethod = invocableMethod.wrapConcurrentResult(result); } // 執行方法 -》 invocableMethod.invokeAndHandle(webRequest, mavContainer); // 若是是異步請求,同步返回null if (asyncManager.isConcurrentHandlingStarted()) { return null; } // 返回ModelAndView -》 return getModelAndView(mavContainer, modelFactory, webRequest); } finally { // 請求完成-》 webRequest.requestCompleted(); } }
進入到這個方法org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#getDataBinderFactory
private WebDataBinderFactory getDataBinderFactory(HandlerMethod handlerMethod) throws Exception { // 獲取業務方法的handler類型 Class<?> handlerType = handlerMethod.getBeanType(); // 根據業務handler類型獲取方法 Set<Method> methods = this.initBinderCache.get(handlerType); if (methods == null) { // 查詢業務handler的方法有@InitBinder註解的方法 methods = MethodIntrospector.selectMethods(handlerType, INIT_BINDER_METHODS); this.initBinderCache.put(handlerType, methods); } List<InvocableHandlerMethod> initBinderMethods = new ArrayList<InvocableHandlerMethod>(); // Global methods first for (Entry<ControllerAdviceBean, Set<Method>> entry : this.initBinderAdviceCache.entrySet()) { // 檢查業務handler上面是否有@ControllerAdvice註解 if (entry.getKey().isApplicableToBeanType(handlerType)) { Object bean = entry.getKey().resolveBean(); for (Method method : entry.getValue()) { // 建立InitBinderMethod -》 initBinderMethods.add(createInitBinderMethod(bean, method)); } } } for (Method method : methods) { Object bean = handlerMethod.getBean(); initBinderMethods.add(createInitBinderMethod(bean, method)); } return createDataBinderFactory(initBinderMethods); } private InvocableHandlerMethod createInitBinderMethod(Object bean, Method method) { InvocableHandlerMethod binderMethod = new InvocableHandlerMethod(bean, method); // 設置initBinder的參數解析器 binderMethod.setHandlerMethodArgumentResolvers(this.initBinderArgumentResolvers); binderMethod.setDataBinderFactory(new DefaultDataBinderFactory(this.webBindingInitializer)); binderMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer); return binderMethod; }
進入到這個方法org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#createInitBinderMethod
private InvocableHandlerMethod createInitBinderMethod(Object bean, Method method) { InvocableHandlerMethod binderMethod = new InvocableHandlerMethod(bean, method); // 設置initBinder的參數解析器 binderMethod.setHandlerMethodArgumentResolvers(this.initBinderArgumentResolvers); binderMethod.setDataBinderFactory(new DefaultDataBinderFactory(this.webBindingInitializer)); binderMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer); return binderMethod; }
往上返回到這個方法org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#getModelFactory
private ModelFactory getModelFactory(HandlerMethod handlerMethod, WebDataBinderFactory binderFactory) { // 獲取有@SessionAttribute註解的handler -》 SessionAttributesHandler sessionAttrHandler = getSessionAttributesHandler(handlerMethod); Class<?> handlerType = handlerMethod.getBeanType(); Set<Method> methods = this.modelAttributeCache.get(handlerType); if (methods == null) { // 獲取handler中有@RequestMapping、@ModelAttribute的方法 methods = MethodIntrospector.selectMethods(handlerType, MODEL_ATTRIBUTE_METHODS); this.modelAttributeCache.put(handlerType, methods); } List<InvocableHandlerMethod> attrMethods = new ArrayList<InvocableHandlerMethod>(); // Global methods first for (Entry<ControllerAdviceBean, Set<Method>> entry : this.modelAttributeAdviceCache.entrySet()) { // 若是handler上有@ControllerAdvice -》 if (entry.getKey().isApplicableToBeanType(handlerType)) { Object bean = entry.getKey().resolveBean(); for (Method method : entry.getValue()) { // 建立ModelAttributeMethod -》 attrMethods.add(createModelAttributeMethod(binderFactory, bean, method)); } } } for (Method method : methods) { Object bean = handlerMethod.getBean(); attrMethods.add(createModelAttributeMethod(binderFactory, bean, method)); } return new ModelFactory(attrMethods, binderFactory, sessionAttrHandler); }
進入到這個方法org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#getSessionAttributesHandler
private SessionAttributesHandler getSessionAttributesHandler(HandlerMethod handlerMethod) { Class<?> handlerType = handlerMethod.getBeanType(); // 從緩存中獲取SessionAttributesHandler SessionAttributesHandler sessionAttrHandler = this.sessionAttributesHandlerCache.get(handlerType); if (sessionAttrHandler == null) { synchronized (this.sessionAttributesHandlerCache) { sessionAttrHandler = this.sessionAttributesHandlerCache.get(handlerType); if (sessionAttrHandler == null) { sessionAttrHandler = new SessionAttributesHandler(handlerType, sessionAttributeStore); this.sessionAttributesHandlerCache.put(handlerType, sessionAttrHandler); } } } return sessionAttrHandler; }
進入到這個方法org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#createModelAttributeMethod
private InvocableHandlerMethod createModelAttributeMethod(WebDataBinderFactory factory, Object bean, Method method) { InvocableHandlerMethod attrMethod = new InvocableHandlerMethod(bean, method); // 設置參數解析器 attrMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers); attrMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer); attrMethod.setDataBinderFactory(factory); return attrMethod; }
往上返回到這個方法org.springframework.web.method.annotation.ModelFactory#initModel
public void initModel(NativeWebRequest request, ModelAndViewContainer container, HandlerMethod handlerMethod) throws Exception { // 從session中獲取屬性值 -》 Map<String, ?> sessionAttributes = this.sessionAttributesHandler.retrieveAttributes(request); // 合併session參數 -》 container.mergeAttributes(sessionAttributes); // 執行有@ModelAttribute的方法 -》 invokeModelAttributeMethods(request, container); // 查找handle方法上@ModelAttribute的參數 -》 for (String name : findSessionAttributeArguments(handlerMethod)) { if (!container.containsAttribute(name)) { Object value = this.sessionAttributesHandler.retrieveAttribute(request, name); if (value == null) { throw new HttpSessionRequiredException("Expected session attribute '" + name + "'", name); } container.addAttribute(name, value); } } }
進入這個方法org.springframework.web.method.annotation.SessionAttributesHandler#retrieveAttributes
public Map<String, Object> retrieveAttributes(WebRequest request) { Map<String, Object> attributes = new HashMap<String, Object>(); for (String name : this.knownAttributeNames) { Object value = this.sessionAttributeStore.retrieveAttribute(request, name); if (value != null) { attributes.put(name, value); } } return attributes; }
往上返回這個方法org.springframework.web.method.support.ModelAndViewContainer#mergeAttributes
public ModelAndViewContainer mergeAttributes(Map<String, ?> attributes) { // -》 getModel().mergeAttributes(attributes); return this; }
進入這個方法org.springframework.web.method.support.ModelAndViewContainer#getModel
public ModelMap getModel() { if (useDefaultModel()) { return this.defaultModel; } else { if (this.redirectModel == null) { // model就是一個linkedHashMap this.redirectModel = new ModelMap(); } return this.redirectModel; } }
往上返回到這個方法org.springframework.web.method.annotation.ModelFactory#invokeModelAttributeMethods
private void invokeModelAttributeMethods(NativeWebRequest request, ModelAndViewContainer container) throws Exception { while (!this.modelMethods.isEmpty()) { InvocableHandlerMethod modelMethod = getNextModelMethod(container).getHandlerMethod(); ModelAttribute ann = modelMethod.getMethodAnnotation(ModelAttribute.class); if (container.containsAttribute(ann.name())) { if (!ann.binding()) { container.setBindingDisabled(ann.name()); } continue; } // 執行請求 -》 Object returnValue = modelMethod.invokeForRequest(request, container); if (!modelMethod.isVoid()){ // 根據返回值和返回值類型獲取返回值解析器 -》 String returnValueName = getNameForReturnValue(returnValue, modelMethod.getReturnType()); if (!ann.binding()) { container.setBindingDisabled(returnValueName); } // modelAndView容器不包含這個返回值就添加 if (!container.containsAttribute(returnValueName)) { container.addAttribute(returnValueName, returnValue); } } } }
進入這個方法org.springframework.web.method.support.InvocableHandlerMethod#invokeForRequest
public Object invokeForRequest(NativeWebRequest request, ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception { // 解析請求參數值 -》 Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs); if (logger.isTraceEnabled()) { logger.trace("Invoking '" + ClassUtils.getQualifiedMethodName(getMethod(), getBeanType()) + "' with arguments " + Arrays.toString(args)); } // 執行方法 Object returnValue = doInvoke(args); if (logger.isTraceEnabled()) { logger.trace("Method [" + ClassUtils.getQualifiedMethodName(getMethod(), getBeanType()) + "] returned [" + returnValue + "]"); } return returnValue; }
進入這個方法org.springframework.web.method.support.InvocableHandlerMethod#getMethodArgumentValues
private Object[] getMethodArgumentValues(NativeWebRequest request, ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception { MethodParameter[] parameters = getMethodParameters(); Object[] args = new Object[parameters.length]; for (int i = 0; i < parameters.length; i++) { MethodParameter parameter = parameters[i]; parameter.initParameterNameDiscovery(this.parameterNameDiscoverer); args[i] = resolveProvidedArgument(parameter, providedArgs); if (args[i] != null) { continue; } if (this.argumentResolvers.supportsParameter(parameter)) { try { // 解析參數 -》 args[i] = this.argumentResolvers.resolveArgument( parameter, mavContainer, request, this.dataBinderFactory); continue; } catch (Exception ex) { if (logger.isDebugEnabled()) { logger.debug(getArgumentResolutionErrorMessage("Failed to resolve", i), ex); } throw ex; } } if (args[i] == null) { throw new IllegalStateException("Could not resolve method parameter at index " + parameter.getParameterIndex() + " in " + parameter.getMethod().toGenericString() + ": " + getArgumentResolutionErrorMessage("No suitable resolver for", i)); } } return args; }
進入這個方法org.springframework.web.method.support.HandlerMethodArgumentResolverComposite#resolveArgument
@Override public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { // 根據參數獲取參數解析器 -》 HandlerMethodArgumentResolver resolver = getArgumentResolver(parameter); if (resolver == null) { throw new IllegalArgumentException("Unknown parameter type [" + parameter.getParameterType().getName() + "]"); } // 參數解析 return resolver.resolveArgument(parameter, mavContainer, webRequest, binderFactory); }
進入這個方法org.springframework.web.method.support.HandlerMethodArgumentResolverComposite#getArgumentResolver
private HandlerMethodArgumentResolver getArgumentResolver(MethodParameter parameter) { HandlerMethodArgumentResolver result = this.argumentResolverCache.get(parameter); if (result == null) { for (HandlerMethodArgumentResolver methodArgumentResolver : this.argumentResolvers) { if (logger.isTraceEnabled()) { logger.trace("Testing if argument resolver [" + methodArgumentResolver + "] supports [" + parameter.getGenericParameterType() + "]"); } // 方法參數解析器解析參數值 if (methodArgumentResolver.supportsParameter(parameter)) { result = methodArgumentResolver; this.argumentResolverCache.put(parameter, result); break; } } } return result; }
往上返回到這個方法org.springframework.web.method.annotation.ModelFactory#getNameForReturnValue
public static String getNameForReturnValue(Object returnValue, MethodParameter returnType) { // 獲取返回值類型上的@ModelAttribute ModelAttribute ann = returnType.getMethodAnnotation(ModelAttribute.class); if (ann != null && StringUtils.hasText(ann.value())) { return ann.value(); } else { Method method = returnType.getMethod(); Class<?> containingClass = returnType.getContainingClass(); Class<?> resolvedType = GenericTypeResolver.resolveReturnType(method, containingClass); return Conventions.getVariableNameForReturnType(method, resolvedType, returnValue); } }
往上返回這個方法org.springframework.web.method.annotation.ModelFactory#findSessionAttributeArguments
private List<String> findSessionAttributeArguments(HandlerMethod handlerMethod) { List<String> result = new ArrayList<String>(); for (MethodParameter parameter : handlerMethod.getMethodParameters()) { if (parameter.hasParameterAnnotation(ModelAttribute.class)) { // 獲取@ModelAttribute配置的參數名稱 -》 String name = getNameForParameter(parameter); Class<?> paramType = parameter.getParameterType(); if (this.sessionAttributesHandler.isHandlerSessionAttribute(name, paramType)) { result.add(name); } } } return result; }
進入這個方法org.springframework.web.method.annotation.ModelFactory#getNameForParameter
public static String getNameForParameter(MethodParameter parameter) { ModelAttribute ann = parameter.getParameterAnnotation(ModelAttribute.class); String name = (ann != null ? ann.value() : null); return (StringUtils.hasText(name) ? name : Conventions.getVariableNameForParameter(parameter)); }
往上返回到這個方法org.springframework.web.context.request.async.WebAsyncUtils#createAsyncWebRequest
public static AsyncWebRequest createAsyncWebRequest(HttpServletRequest request, HttpServletResponse response) { return (startAsyncAvailable ? AsyncWebRequestFactory.createStandardAsyncWebRequest(request, response) : new NoSupportAsyncWebRequest(request, response)); }
往上返回這個方法org.springframework.web.context.request.async.WebAsyncUtils#getAsyncManager(javax.servlet.ServletRequest)
public static WebAsyncManager getAsyncManager(ServletRequest servletRequest) { WebAsyncManager asyncManager = null; // 從request中獲取請求管理器 Object asyncManagerAttr = servletRequest.getAttribute(WEB_ASYNC_MANAGER_ATTRIBUTE); if (asyncManagerAttr instanceof WebAsyncManager) { asyncManager = (WebAsyncManager) asyncManagerAttr; } // 若是沒有就建立後綁定到request中 if (asyncManager == null) { asyncManager = new WebAsyncManager(); servletRequest.setAttribute(WEB_ASYNC_MANAGER_ATTRIBUTE, asyncManager); } return asyncManager; }
往上返回這個方法org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod#invokeAndHandle
public 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()) { mavContainer.setRequestHandled(true); return; } } else if (StringUtils.hasText(getResponseStatusReason())) { mavContainer.setRequestHandled(true); return; } mavContainer.setRequestHandled(false); try { // 執行returnHandler -》 this.returnValueHandlers.handleReturnValue( returnValue, getReturnValueType(returnValue), mavContainer, webRequest); } catch (Exception ex) { if (logger.isTraceEnabled()) { logger.trace(getReturnValueHandlingErrorMessage("Error handling return value", returnValue), ex); } throw ex; } }
進入這個方法org.springframework.web.method.support.InvocableHandlerMethod#invokeForRequest
public Object invokeForRequest(NativeWebRequest request, ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception { // 解析請求參數值 -》 Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs); if (logger.isTraceEnabled()) { logger.trace("Invoking '" + ClassUtils.getQualifiedMethodName(getMethod(), getBeanType()) + "' with arguments " + Arrays.toString(args)); } // 執行方法 Object returnValue = doInvoke(args); if (logger.isTraceEnabled()) { logger.trace("Method [" + ClassUtils.getQualifiedMethodName(getMethod(), getBeanType()) + "] returned [" + returnValue + "]"); } return returnValue; }
這裏前面介紹過了。
進入這個方法org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod#setResponseStatus
private void setResponseStatus(ServletWebRequest webRequest) throws IOException { HttpStatus status = getResponseStatus(); if (status == null) { return; } String reason = getResponseStatusReason(); if (StringUtils.hasText(reason)) { webRequest.getResponse().sendError(status.value(), reason); } else { webRequest.getResponse().setStatus(status.value()); } // To be picked up by RedirectView webRequest.getRequest().setAttribute(View.RESPONSE_STATUS_ATTRIBUTE, status); }
往上返回這個方法org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite#handleReturnValue
@Override public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception { // 根據返回值和返回值類型找到handler -》 HandlerMethodReturnValueHandler handler = selectHandler(returnValue, returnType); if (handler == null) { throw new IllegalArgumentException("Unknown return value type: " + returnType.getParameterType().getName()); } // 根據returnHandler方法執行的結果包裝最後要返回視圖的值 -》 handler.handleReturnValue(returnValue, returnType, mavContainer, webRequest); }
進入到這個方法org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite#selectHandler
private HandlerMethodReturnValueHandler selectHandler(Object value, MethodParameter returnType) { // 是不是異步返回值 boolean isAsyncValue = isAsyncReturnValue(value, returnType); for (HandlerMethodReturnValueHandler handler : this.returnValueHandlers) { if (isAsyncValue && !(handler instanceof AsyncHandlerMethodReturnValueHandler)) { continue; } if (handler.supportsReturnType(returnType)) { return handler; } } return null; }
往上返回這個方法org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#getModelAndView
private ModelAndView getModelAndView(ModelAndViewContainer mavContainer, ModelFactory modelFactory, NativeWebRequest webRequest) throws Exception { // 更新model -》 modelFactory.updateModel(webRequest, mavContainer); if (mavContainer.isRequestHandled()) { return null; } ModelMap model = mavContainer.getModel(); // 建立modelAndView對象 ModelAndView mav = new ModelAndView(mavContainer.getViewName(), model, mavContainer.getStatus()); // 是否是string的view視圖 if (!mavContainer.isViewReference()) { mav.setView((View) mavContainer.getView()); } if (model instanceof RedirectAttributes) { Map<String, ?> flashAttributes = ((RedirectAttributes) model).getFlashAttributes(); HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class); RequestContextUtils.getOutputFlashMap(request).putAll(flashAttributes); } return mav; }
進入這個方法org.springframework.web.method.annotation.ModelFactory#updateModel
public void updateModel(NativeWebRequest request, ModelAndViewContainer container) throws Exception { ModelMap defaultModel = container.getDefaultModel(); if (container.getSessionStatus().isComplete()){ this.sessionAttributesHandler.cleanupAttributes(request); } else { this.sessionAttributesHandler.storeAttributes(request, defaultModel); } if (!container.isRequestHandled() && container.getModel() == defaultModel) { // 更新綁定結果-》 updateBindingResult(request, defaultModel); } }
進入這個方法org.springframework.web.method.annotation.ModelFactory#updateBindingResult
private void updateBindingResult(NativeWebRequest request, ModelMap model) throws Exception { List<String> keyNames = new ArrayList<String>(model.keySet()); for (String name : keyNames) { Object value = model.get(name); if (isBindingCandidate(name, value)) { String bindingResultKey = BindingResult.MODEL_KEY_PREFIX + name; if (!model.containsAttribute(bindingResultKey)) { // 建立數據綁定器-》 WebDataBinder dataBinder = this.dataBinderFactory.createBinder(request, value, name); model.put(bindingResultKey, dataBinder.getBindingResult()); } } } }
進入到這個方法org.springframework.web.bind.support.DefaultDataBinderFactory#createBinder
@Override public final WebDataBinder createBinder(NativeWebRequest webRequest, Object target, String objectName) throws Exception { // 建立數據綁定對象-》 WebDataBinder dataBinder = createBinderInstance(target, objectName, webRequest); if (this.initializer != null) { // WebBindingInitializer初始化綁定器 -》 this.initializer.initBinder(dataBinder, webRequest); } // 初始化綁定器-》 initBinder(dataBinder, webRequest); return dataBinder; }
進入這個方法org.springframework.web.method.annotation.InitBinderDataBinderFactory#initBinder
@Override public void initBinder(WebDataBinder dataBinder, NativeWebRequest request) throws Exception { for (InvocableHandlerMethod binderMethod : this.binderMethods) { // 若是方法上有@InitBinder註解-》 if (isBinderMethodApplicable(binderMethod, dataBinder)) { // 執行請求-》 Object returnValue = binderMethod.invokeForRequest(request, null, dataBinder); if (returnValue != null) { throw new IllegalStateException( "@InitBinder methods must not return a value (should be void): " + binderMethod); } } } }
進入這個方法org.springframework.web.method.annotation.InitBinderDataBinderFactory#isBinderMethodApplicable
protected boolean isBinderMethodApplicable(HandlerMethod initBinderMethod, WebDataBinder dataBinder) { InitBinder ann = initBinderMethod.getMethodAnnotation(InitBinder.class); String[] names = ann.value(); return (ObjectUtils.isEmpty(names) || ObjectUtils.containsElement(names, dataBinder.getObjectName())); }
往上返回這個方法org.springframework.web.method.support.InvocableHandlerMethod#invokeForRequest
public Object invokeForRequest(NativeWebRequest request, ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception { // 解析請求參數值 -》 Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs); if (logger.isTraceEnabled()) { logger.trace("Invoking '" + ClassUtils.getQualifiedMethodName(getMethod(), getBeanType()) + "' with arguments " + Arrays.toString(args)); } // 執行方法 Object returnValue = doInvoke(args); if (logger.isTraceEnabled()) { logger.trace("Method [" + ClassUtils.getQualifiedMethodName(getMethod(), getBeanType()) + "] returned [" + returnValue + "]"); } return returnValue; }
這裏前面介紹過了。
往上返回到這個方法org.springframework.web.context.request.AbstractRequestAttributes#requestCompleted
public void requestCompleted() { // 執行請求回調 executeRequestDestructionCallbacks(); // 更新session綁定參數 updateAccessedSessionAttributes(); this.requestActive = false; }
往上返回到這個方法org.springframework.web.servlet.DispatcherServlet#doDispatch這一行
// Actually invoke the handler.執行handler -》 mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
說到最後
本次源碼解析僅表明我的觀點,僅供參考。