DispatcherServlet源码注解分析
Posted STM32STM32STM32
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了DispatcherServlet源码注解分析相关的知识,希望对你有一定的参考价值。
DispatcherServlet的介绍与工作流程
DispatcherServlet是SpringMVC的前端分发控制器,用于处理客户端请求,然后交给对应的handler进行处理,返回对应的模型和视图,视图解析器根据视图名称进行视图渲染,然后返回给DispatcherServlet,该分发servlet将渲染好的视图页面呈现给用户。
工作流程图
下面是对DispatcherServlet的源码注解分析,后期将会不断完善
1 /* 2 * Copyright 2002-2017 the original author or authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package org.springframework.web.servlet; 18 19 import java.io.IOException; 20 import java.util.ArrayList; 21 import java.util.Collections; 22 import java.util.Enumeration; 23 import java.util.HashMap; 24 import java.util.HashSet; 25 import java.util.LinkedList; 26 import java.util.List; 27 import java.util.Locale; 28 import java.util.Map; 29 import java.util.Properties; 30 import java.util.Set; 31 import javax.servlet.ServletContext; 32 import javax.servlet.ServletException; 33 import javax.servlet.http.HttpServletRequest; 34 import javax.servlet.http.HttpServletResponse; 35 36 import org.apache.commons.logging.Log; 37 import org.apache.commons.logging.LogFactory; 38 39 import org.springframework.beans.factory.BeanFactoryUtils; 40 import org.springframework.beans.factory.BeanInitializationException; 41 import org.springframework.beans.factory.NoSuchBeanDefinitionException; 42 import org.springframework.context.ApplicationContext; 43 import org.springframework.context.ConfigurableApplicationContext; 44 import org.springframework.context.i18n.LocaleContext; 45 import org.springframework.core.annotation.AnnotationAwareOrderComparator; 46 import org.springframework.core.io.ClassPathResource; 47 import org.springframework.core.io.support.PropertiesLoaderUtils; 48 import org.springframework.http.server.ServletServerHttpRequest; 49 import org.springframework.ui.context.ThemeSource; 50 import org.springframework.util.ClassUtils; 51 import org.springframework.util.StringUtils; 52 import org.springframework.web.context.WebApplicationContext; 53 import org.springframework.web.context.request.ServletWebRequest; 54 import org.springframework.web.context.request.async.WebAsyncManager; 55 import org.springframework.web.context.request.async.WebAsyncUtils; 56 import org.springframework.web.multipart.MultipartException; 57 import org.springframework.web.multipart.MultipartHttpServletRequest; 58 import org.springframework.web.multipart.MultipartResolver; 59 import org.springframework.web.util.NestedServletException; 60 import org.springframework.web.util.WebUtils; 61 62 /** 63 * Central dispatcher for HTTP request handlers/controllers, e.g. for web UI controllers 64 * or HTTP-based remote service exporters. Dispatches to registered handlers for processing 65 * a web request, providing convenient mapping and exception handling facilities. 66 * 67 * <p>This servlet is very flexible: It can be used with just about any workflow, with the 68 * installation of the appropriate adapter classes. It offers the following functionality 69 * that distinguishes it from other request-driven web MVC frameworks: 70 * 71 * <ul> 72 * <li>It is based around a JavaBeans configuration mechanism. 73 * 74 * <li>It can use any {@link HandlerMapping} implementation - pre-built or provided as part 75 * of an application - to control the routing of requests to handler objects. Default is 76 * {@link org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping} and 77 * {@link org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping}. 78 * HandlerMapping objects can be defined as beans in the servlet\'s application context, 79 * implementing the HandlerMapping interface, overriding the default HandlerMapping if 80 * present. HandlerMappings can be given any bean name (they are tested by type). 81 * 82 * <li>It can use any {@link HandlerAdapter}; this allows for using any handler interface. 83 * Default adapters are {@link org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter}, 84 * {@link org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter}, for Spring\'s 85 * {@link org.springframework.web.HttpRequestHandler} and 86 * {@link org.springframework.web.servlet.mvc.Controller} interfaces, respectively. A default 87 * {@link org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter} 88 * will be registered as well. HandlerAdapter objects can be added as beans in the 89 * application context, overriding the default HandlerAdapters. Like HandlerMappings, 90 * HandlerAdapters can be given any bean name (they are tested by type). 91 * 92 * <li>The dispatcher\'s exception resolution strategy can be specified via a 93 * {@link HandlerExceptionResolver}, for example mapping certain exceptions to error pages. 94 * Default are 95 * {@link org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver}, 96 * {@link org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver}, and 97 * {@link org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver}. 98 * These HandlerExceptionResolvers can be overridden through the application context. 99 * HandlerExceptionResolver can be given any bean name (they are tested by type). 100 * 101 * <li>Its view resolution strategy can be specified via a {@link ViewResolver} 102 * implementation, resolving symbolic view names into View objects. Default is 103 * {@link org.springframework.web.servlet.view.InternalResourceViewResolver}. 104 * ViewResolver objects can be added as beans in the application context, overriding the 105 * default ViewResolver. ViewResolvers can be given any bean name (they are tested by type). 106 * 107 * <li>If a {@link View} or view name is not supplied by the user, then the configured 108 * {@link RequestToViewNameTranslator} will translate the current request into a view name. 109 * The corresponding bean name is "viewNameTranslator"; the default is 110 * {@link org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator}. 111 * 112 * <li>The dispatcher\'s strategy for resolving multipart requests is determined by a 113 * {@link org.springframework.web.multipart.MultipartResolver} implementation. 114 * Implementations for Apache Commons FileUpload and Servlet 3 are included; the typical 115 * choice is {@link org.springframework.web.multipart.commons.CommonsMultipartResolver}. 116 * The MultipartResolver bean name is "multipartResolver"; default is none. 117 * 118 * <li>Its locale resolution strategy is determined by a {@link LocaleResolver}. 119 * Out-of-the-box implementations work via HTTP accept header, cookie, or session. 120 * The LocaleResolver bean name is "localeResolver"; default is 121 * {@link org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver}. 122 * 123 * <li>Its theme resolution strategy is determined by a {@link ThemeResolver}. 124 * Implementations for a fixed theme and for cookie and session storage are included. 125 * The ThemeResolver bean name is "themeResolver"; default is 126 * {@link org.springframework.web.servlet.theme.FixedThemeResolver}. 127 * </ul> 128 * 129 * <p><b>NOTE: The {@code @RequestMapping} annotation will only be processed if a 130 * corresponding {@code HandlerMapping} (for type-level annotations) and/or 131 * {@code HandlerAdapter} (for method-level annotations) is present in the dispatcher.</b> 132 * This is the case by default. However, if you are defining custom {@code HandlerMappings} 133 * or {@code HandlerAdapters}, then you need to make sure that a corresponding custom 134 * {@code DefaultAnnotationHandlerMapping} and/or {@code AnnotationMethodHandlerAdapter} 135 * is defined as well - provided that you intend to use {@code @RequestMapping}. 136 * 137 * <p><b>A web application can define any number of DispatcherServlets.</b> 138 * Each servlet will operate in its own namespace, loading its own application context 139 * with mappings, handlers, etc. Only the root application context as loaded by 140 * {@link org.springframework.web.context.ContextLoaderListener}, if any, will be shared. 141 * 142 * <p>As of Spring 3.1, {@code DispatcherServlet} may now be injected with a web 143 * application context, rather than creating its own internally. This is useful in Servlet 144 * 3.0+ environments, which support programmatic registration of servlet instances. 145 * See the {@link #DispatcherServlet(WebApplicationContext)} javadoc for details. 146 * 147 * @author Rod Johnson 148 * @author Juergen Hoeller 149 * @author Rob Harrop 150 * @author Chris Beams 151 * @author Rossen Stoyanchev 152 * @see org.springframework.web.HttpRequestHandler 153 * @see org.springframework.web.servlet.mvc.Controller 154 * @see org.springframework.web.context.ContextLoaderListener 155 */ 156 @SuppressWarnings("serial") 157 public class DispatcherServlet extends FrameworkServlet { 158 159 /** Well-known name for the MultipartResolver object in the bean factory for this namespace. */ 160 public static final String MULTIPART_RESOLVER_BEAN_NAME = "multipartResolver"; 161 162 /** Well-known name for the LocaleResolver object in the bean factory for this namespace. */ 163 public static final String LOCALE_RESOLVER_BEAN_NAME = "localeResolver"; 164 165 /** Well-known name for the ThemeResolver object in the bean factory for this namespace. */ 166 public static final String THEME_RESOLVER_BEAN_NAME = "themeResolver"; 167 168 /** 169 * Well-known name for the HandlerMapping object in the bean factory for this namespace. 170 * Only used when "detectAllHandlerMappings" is turned off. 171 * @see #setDetectAllHandlerMappings 172 */ 173 public static final String HANDLER_MAPPING_BEAN_NAME = "handlerMapping"; 174 175 /** 176 * Well-known name for the HandlerAdapter object in the bean factory for this namespace. 177 * Only used when "detectAllHandlerAdapters" is turned off. 178 * @see #setDetectAllHandlerAdapters 179 */ 180 public static final String HANDLER_ADAPTER_BEAN_NAME = "handlerAdapter"; 181 182 /** 183 * Well-known name for the HandlerExceptionResolver object in the bean factory for this namespace. 184 * Only used when "detectAllHandlerExceptionResolvers" is turned off. 185 * @see #setDetectAllHandlerExceptionResolvers 186 */ 187 public static final String HANDLER_EXCEPTION_RESOLVER_BEAN_NAME = "handlerExceptionResolver"; 188 189 /** 190 * Well-known name for the RequestToViewNameTranslator object in the bean factory for this namespace. 191 */ 192 public static final String REQUEST_TO_VIEW_NAME_TRANSLATOR_BEAN_NAME = "viewNameTranslator"; 193 194 /** 195 * Well-known name for the ViewResolver object in the bean factory for this namespace. 196 * Only used when "detectAllViewResolvers" is turned off. 197 * @see #setDetectAllViewResolvers 198 */ 199 public static final String VIEW_RESOLVER_BEAN_NAME = "viewResolver"; 200 201 /** 202 * Well-known name for the FlashMapManager object in the bean factory for this namespace. 203 */ 204 public static final String FLASH_MAP_MANAGER_BEAN_NAME = "flashMapManager"; 205 206 /** 207 * Request attribute to hold the current web application context. 208 * Otherwise only the global web app context is obtainable by tags etc. 209 * @see org.springframework.web.servlet.support.RequestContextUtils#findWebApplicationContext 210 */ 211 public static final String WEB_APPLICATION_CONTEXT_ATTRIBUTE = DispatcherServlet.class.getName() + ".CONTEXT"; 212 213 /** 214 * Request attribute to hold the current LocaleResolver, retrievable by views. 215 * @see org.springframework.web.servlet.support.RequestContextUtils#getLocaleResolver 216 */ 217 public static final String LOCALE_RESOLVER_ATTRIBUTE = DispatcherServlet.class.getName() + ".LOCALE_RESOLVER"; 218 219 /** 220 * Request attribute to hold the current ThemeResolver, retrievable by views. 221 * @see org.springframework.web.servlet.support.RequestContextUtils#getThemeResolver 222 */ 223 public static final String THEME_RESOLVER_ATTRIBUTE = DispatcherServlet.class.getName() + ".THEME_RESOLVER"; 224 225 /** 226 * Request attribute to hold the current ThemeSource, retrievable by views. 227 * @see org.springframework.web.servlet.support.RequestContextUtils#getThemeSource 228 */ 229 public static final String THEME_SOURCE_ATTRIBUTE = DispatcherServlet.class.getName() + ".THEME_SOURCE"; 230 231 /** 232 * Name of request attribute that holds a read-only {@code Map<String,?>} 233 * with "input" flash attributes saved by a previous request, if any. 234 * @see org.springframework.web.servlet.support.RequestContextUtils#getInputFlashMap(HttpServletRequest) 235 */ 236 public static final String INPUT_FLASH_MAP_ATTRIBUTE = DispatcherServlet.class.getName() + ".INPUT_FLASH_MAP"; 237 238 /** 239 * Name of request attribute that holds the "output" {@link FlashMap} with 240 * attributes to save for a subsequent request. 241 * @see org.springframework.web.servlet.support.RequestContextUtils#getOutputFlashMap(HttpServletRequest) 242 */ 243 public static final String OUTPUT_FLASH_MAP_ATTRIBUTE = DispatcherServlet.class.getName() + ".OUTPUT_FLASH_MAP"; 244 245 /** 246 * Name of request attribute that holds the {@link FlashMapManager}. 247 * @see org.springframework.web.servlet.support.RequestContextUtils#getFlashMapManager(HttpServletRequest) 248 */ 249 public static final String FLASH_MAP_MANAGER_ATTRIBUTE = DispatcherServlet.class.getName() + ".FLASH_MAP_MANAGER"; 250 251 /** 252 * Name of request attribute that exposes an Exception resolved with an 253 * {@link HandlerExceptionResolver} but where no view was rendered 254 * (e.g. setting the status code). 255 */ 256 public static final String EXCEPTION_ATTRIBUTE = DispatcherServlet.class.getName() + ".EXCEPTION"; 257 258 /** Log category to use when no mapped handler is found for a request. */ 259 public static final String PAGE_NOT_FOUND_LOG_CATEGORY = "org.springframework.web.servlet.PageNotFound"; 260 261 /** 262 * Name of the class path resource (relative to the DispatcherServlet class) 263 * that defines DispatcherServlet\'s default strategy names. 264 */ 265 private static final String DEFAULT_STRATEGIES_PATH = "DispatcherServlet.properties"; 266 267 /** 268 * Common prefix that DispatcherServlet\'s default strategy attributes start with. 269 */ 270 private static final String DEFAULT_STRATEGIES_PREFIX = "org.springframework.web.servlet"; 271 272 /** Additional logger to use when no mapped handler is found for a request. */ 273 protected static final Log pageNotFoundLogger = LogFactory.getLog(PAGE_NOT_FOUND_LOG_CATEGORY); 274 275 private static final Properties defaultStrategies; 276 277 static { 278 // Load default strategy implementations from properties file. 279 // This is currently strictly internal and not meant to be customized 280 // by application developers. 281 try { 282 ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, DispatcherServlet.class); 283 defaultStrategies = PropertiesLoaderUtils.loadProperties(resource); 284 } 285 catch (IOException ex) { 286 throw new IllegalStateException("Could not load \'" + DEFAULT_STRATEGIES_PATH + "\': " + ex.getMessage()); 287 } 288 } 289 290 /** Detect all HandlerMappings or just expect "handlerMapping" bean? */ 291 private boolean detectAllHandlerMappings = true; 292 293 /** Detect all HandlerAdapters or just expect "handlerAdapter" bean? */ 294 private boolean detectAllHandlerAdapters = true; 295 296 /** Detect all HandlerExceptionResolvers or just expect "handlerExceptionResolver" bean? */ 297 private boolean detectAllHandlerExceptionResolvers = true; 298 299 /** Detect all ViewResolvers or just expect "viewResolver" bean? */ 300 private boolean detectAllViewResolvers = true; 301 302 /** Throw a NoHandlerFoundException if no Handler was found to process this request? **/ 303 private boolean throwExceptionIfNoHandlerFound = false; 304 305 /** Perform cleanup of request attributes after include request? */ 306 private boolean cleanupAfterInclude = true; 307 308 /** MultipartResolver used by this servlet */ 309 private MultipartResolver multipartResolver; 310 311 /** LocaleResolver used by this servlet */ 312 private LocaleResolver localeResolver; 313 314 /** ThemeResolver used by this servlet */ 315 private ThemeResolver themeResolver; 316 317 /** List of HandlerMappings used by this servlet */ 318 private List<HandlerMapping> handlerMappings; 319 320 /** List of HandlerAdapters used by this servlet */ 321 private List<HandlerAdapter> handlerAdapters; 322 323 /** List of HandlerExceptionResolvers used by this servlet */ 324 private List<HandlerExceptionResolver> handlerExceptionResolvers; 325 326 /** RequestToViewNameTranslator used by this servlet */ 327 private RequestToViewNameTranslator viewNameTranslator; 328 329 /** FlashMapManager used by this servlet */ 330 private FlashMapManager flashMapManager; 331 332 /** List of ViewResolvers used by this servlet */ 333 private List<ViewResolver> viewResolvers; 334 335 336 /** 337 * Create a new {@code DispatcherServlet} that will create its own internal web 338 * application context based on defaults and values provided through servlet 339 * init-params. Typically used in Servlet 2.5 or earlier environments, where the only 340 * option for servlet registration is through {@code web.xml} which requires the use 341 * of a no-arg constructor. 342 * <p>Calling {@link #setContextConfigLocation} (init-param以上是关于DispatcherServlet源码注解分析的主要内容,如果未能解决你的问题,请参考以下文章
SpringMVC DispatcherServlet执行流程及源码分析
从DispatcherServlet源码分析SpringMVC处理请求的流程
SpringMVC源码分析4:DispatcherServlet如何找到正确的Controller