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

Spring MVC工作原理及源码解析DispatcherServlet实现原理及源码解析

SpringDispatcherServlet源码分析

Java注解及其原理以及分析spring注解解析源码