SpringMVC

在浏览器中输入网址并回车后发生了什么?

在浏览器中输入网址并回车后,浏览器先在本地 hosts 文件中查询域名和 IP 的对应关系,如果有,则向 IP 地址发送请求,如果没有,则去 DNS 服务器查询。

DispatcherServlet

DispatcherServlet 是 SpringMVC 的核心控制器,用于处理 HTTP 请求处理和控制。

dispatcher,即调度员

特点

  • 基于 JavaBean 配置机制
  • 可以使用任何的 HandlerMapping 实现来控制对处理程序对象的请求的路由,默认是 BeanNameUrlHandlerMapping 和 RequestMappingHandlerMapping
  • TODO

主要流程:

1、文件上传解析,如果请求类型是multipart将通过MultipartResolver进行文件上传解析;

2、通过HandlerMapping,将请求映射到处理器(返回一个HandlerExecutionChain,它包括一个处理器、多个HandlerInterceptor拦截器);

3、通过HandlerAdapter支持多种类型的处理器(HandlerExecutionChain中的处理器);

4、通过ViewResolver解析逻辑视图名到具体视图实现;

5、本地化解析;

6、渲染具体的视图等;

7、如果执行过程中遇到异常将交给HandlerExceptionResolver来解析。

最终调用的方法为 doDispatch。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
boolean multipartRequestParsed = false;

WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

try {
ModelAndView mv = null;
Exception dispatchException = null;

try {
//检查是否是文件上传请求
processedRequest = checkMultipart(request);
multipartRequestParsed = (processedRequest != request);

// 获取当期请求的HandlerExecutionChain
mappedHandler = getHandler(processedRequest);
//返回null时。会调用noHandlerFound,抛出异常或返回请求找不到的错误信息
if (mappedHandler == null || mappedHandler.getHandler() == null) {
noHandlerFound(processedRequest, response);
return;
}

// 获取当前请求的处理器适配器
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

// Process last-modified header, if supported by the handler.
String method = request.getMethod();
boolean isGet = "GET".equals(method);
if (isGet || "HEAD".equals(method)) {
long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
if (logger.isDebugEnabled()) {
logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);
}
if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
return;
}
}

if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}

// Actually invoke the handler.
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

if (asyncManager.isConcurrentHandlingStarted()) {
return;
}

applyDefaultViewName(processedRequest, mv);
mappedHandler.applyPostHandle(processedRequest, response, mv);
}
catch (Exception ex) {
dispatchException = ex;
}
catch (Throwable err) {
// As of 4.3, we're processing Errors thrown from handler methods as well,
// making them available for @ExceptionHandler methods and other scenarios.
dispatchException = new NestedServletException("Handler dispatch failed", err);
}
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
catch (Exception ex) {
triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
}
catch (Throwable err) {
triggerAfterCompletion(processedRequest, response, mappedHandler,
new NestedServletException("Handler processing failed", err));
}
finally {
if (asyncManager.isConcurrentHandlingStarted()) {
// Instead of postHandle and afterCompletion
if (mappedHandler != null) {
mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
}
}
else {
// Clean up any resources used by a multipart request.
if (multipartRequestParsed) {
cleanupMultipart(processedRequest);
}
}
}
}

checkMultipart 检查是否是文件上传请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
protected HttpServletRequest checkMultipart(HttpServletRequest request) throws MultipartException {
if (this.multipartResolver != null && this.multipartResolver.isMultipart(request)) {
if (WebUtils.getNativeRequest(request, MultipartHttpServletRequest.class) != null) {
logger.debug("Request is already a MultipartHttpServletRequest - if not in a forward, " +
"this typically results from an additional MultipartFilter in web.xml");
}
//文件解析异常
else if (hasMultipartException(request) ) {
logger.debug("Multipart resolution failed for current request before - " +
"skipping re-resolution for undisturbed error rendering");
}
else {
try {
//请求转化
return this.multipartResolver.resolveMultipart(request);
}
catch (MultipartException ex) {
if (request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE) != null) {
logger.debug("Multipart resolution failed for error dispatch", ex);
// Keep processing error dispatch with regular request handle below
}
else {
throw ex;
}
}
}
}
// 如遇异常或非文件上传请求,则返回原始请求
return request;
}

getHandler

实现如下,返回当前请求对应的 HandlerExecutionChain。

1
2
3
4
5
6
7
8
9
10
11
12
13
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
for (HandlerMapping hm : this.handlerMappings) {
//省略日志信息

//根据请求去获取对应的处理器执行链
HandlerExecutionChain handler = hm.getHandler(request);
if (handler != null) {
return handler;
}
}
//没有找到对应的处理器执行链,则返回null
return null;
}

HandlerMapping 都存放在 handlerMappings 变量中,

1
private List<HandlerMapping> handlerMappings;

在 initStrategies 方法中进行 handlerMappings 的初始化

1
2
3
4
5
6
7
8
9
10
11
12
protected void initStrategies(ApplicationContext context) {
initMultipartResolver(context);
initLocaleResolver(context);
initThemeResolver(context);
//初始化handlerMappings
initHandlerMappings(context);
initHandlerAdapters(context);
initHandlerExceptionResolvers(context);
initRequestToViewNameTranslator(context);
initViewResolvers(context);
initFlashMapManager(context);
}

initHandlerMappings 的作用是初始化所有的HandlerMapping,具体实现如下:

ancestor 祖先

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
private void initHandlerMappings(ApplicationContext context) {
this.handlerMappings = null;

//是否加载所有的 HandlerMapping
if (this.detectAllHandlerMappings) {
// 找到ApplicationContext中的所有HandlerMapping,包括上级的上下文
Map<String, HandlerMapping> matchingBeans =
BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
if (!matchingBeans.isEmpty()) {
this.handlerMappings = new ArrayList<HandlerMapping>(matchingBeans.values());
// 对HandlerMapping进行排序
AnnotationAwareOrderComparator.sort(this.handlerMappings);
}
}
else {
//加载单一的HandlerMapping
try {
//public static final String HANDLER_MAPPING_BEAN_NAME = "handlerMapping";
HandlerMapping hm = context.getBean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class);
this.handlerMappings = Collections.singletonList(hm);
}
catch (NoSuchBeanDefinitionException ex) {
// Ignore, we'll add a default HandlerMapping later.
}
}

// 注册一个默认的HandlerMapping,以保证至少有一个HandlerMapping存在
if (this.handlerMappings == null) {
this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class);
if (logger.isDebugEnabled()) {
logger.debug("No HandlerMappings found in servlet '" + getServletName() + "': using default");
}
}
}

注册默认的HandlerMapping

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
protected <T> List<T> getDefaultStrategies(ApplicationContext context, Class<T> strategyInterface) {
String key = strategyInterface.getName();
String value = defaultStrategies.getProperty(key);
if (value != null) {
String[] classNames = StringUtils.commaDelimitedListToStringArray(value);
List<T> strategies = new ArrayList<T>(classNames.length);
for (String className : classNames) {
try {
Class<?> clazz = ClassUtils.forName(className, DispatcherServlet.class.getClassLoader());
Object strategy = createDefaultStrategy(context, clazz);
strategies.add((T) strategy);
}
catch (ClassNotFoundException ex) {
throw new BeanInitializationException(
"Could not find DispatcherServlet's default strategy class [" + className +
"] for interface [" + key + "]", ex);
}
catch (LinkageError err) {
throw new BeanInitializationException(
"Error loading DispatcherServlet's default strategy class [" + className +
"] for interface [" + key + "]: problem with class file or dependent class", err);
}
}
return strategies;
}
else {
return new LinkedList<T>();
}
}

找不到请求对应的处理器映射器时,执行noHandlerFound方法,响应结束

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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 {
//返回HttpServletResponse.SC_NOT_FOUND,即404
response.sendError(HttpServletResponse.SC_NOT_FOUND);
}
}

获取处理器适配器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
//handlerAdapters 处理器适配器集合,存放所有的处理器适配器
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");
}

HandlerMapping

接口

请求到处理器的映射,如果映射成功返回一个 HandlerExecutionChain 对象(包含一个 Handler 处理器(页面控制器)对象、多个 HandlerInterceptor 拦截器)对象;如 BeanNameUrlHandlerMapping 将 URL 与 Bean 名字映射,映射成功的 Bean 就是此处的处理器。

handler 处理器,其实就是 Controller

former 前面的,前者

wrapped 包裹,包含

optionally 可选

accompanied 伴随着

parameterize 参数

unusual 特殊的,不同寻常的

flexible 灵活的

custom 定制的

开发人员可以实现该接口,但是并没有太大的必要,因为 SpringMVC 提供了两个处理器:BeanNameUrlHandlerMapping 和 DefaultAnnotationHandlerMapping,默认的处理器是 BeanNameUrlHandlerMapping 。

HandlerMapping 实现类可以提供匹配的拦截器,但是这些可选的,并不是必须要提供。处理器始终在 HandlerExecutionChain 实例中,可选地伴随着某些 HandlerInterceptor 实例 。 DispatcherServlet 将以指定的顺讯先调用每个 HandlerInterceptor 的 preHandle 方法, 如果每个 preHandle 方法都返回 true, 才会执行处理器的方法。

参数化映射的能力是 SpringMVC 框架提供的强大的不同寻常的功能。例如,开发人员可以根据 session 状态、cookie 状态或其他变量去编写一个自定义的映射器。其他的 MVC 框架并没有这么灵活。

实现类可以去实现 org.springframework.core.Ordered 接口, 指定排序,以保证 DispatcherServlet 的优先级。无序的实例以最低优先级对待。

使用了模板方法模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
public interface HandlerMapping {

/**
* HttpServletRequest中包含处理器映射路径的属性的名称
* 模式匹配和完整的相关 URI(通常在 DispatcherServlet 的映射中)例外
* relevant 相应的
* scenarios 场景
* 注意:该属性对所有 HandlerMapping 实现来说不是必需的。
* 基于 URL 的 HandlerMappings 通常会支持它,但处理程序不要求在所有场景中都存在此请求属性。
*/
String PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE = HandlerMapping.class.getName() + ".pathWithinHandlerMapping";

/**
* HttpServletRequest包含处理程序映射中最佳匹配模式的属性的名称。
* 注意:该属性对所有 HandlerMapping 实现来说不是必需的。
* 基于 URL 的 HandlerMappings 通常会支持它,但处理程序不要求在所有场景中都存在此请求属性。
*/
String BEST_MATCHING_PATTERN_ATTRIBUTE = HandlerMapping.class.getName() + ".bestMatchingPattern";

/**
* 布尔 HttpServletRequest 属性的名称,指示是否应检查类型级别映射。
* indicate 指示
* 注意: 该属性对所有 HandlerMapping 实现来说不是必需的。
*/
String INTROSPECT_TYPE_LEVEL_MAPPING = HandlerMapping.class.getName() + ".introspectTypeLevelMapping";

/**
* HttpServletRequest 包含 URI 模板映射的属性的名称,将变量名称映射到值。
* 注意:该属性对所有 HandlerMapping 实现来说不是必需的。
* 基于 URL 的 HandlerMappings 通常会支持它,但处理程序不要求在所有场景中都存在此请求属性。
*/
String URI_TEMPLATE_VARIABLES_ATTRIBUTE = HandlerMapping.class.getName() + ".uriTemplateVariables";

/**
* HttpServletRequest 包含具有 URI 变量名称的映射的属性的名称
* 注意:所有 HandlerMapping 实现都不需要此属性,也可能不存在此属性,
* 具体取决于 HandlerMapping 是否配置为保持矩阵变量内容
*/
String MATRIX_VARIABLES_ATTRIBUTE = HandlerMapping.class.getName() + ".matrixVariables";

/**
* HttpServletRequest 包含适用于映射处理程序的可生成 MediaType 集的属性的名称
* 注意:该属性对所有 HandlerMapping 实现来说不是必需的。
* 基于 URL 的 HandlerMappings 通常会支持它,但处理程序不要求在所有场景中都存在此请求属性。
*/
String PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE = HandlerMapping.class.getName() + ".producibleMediaTypes";

/**
* 返回一个 HandlerExecutionChain 对象,该对象中包含了该请求的处理器和所有的拦截器。
* 可以根据请求的 URL, session 的状态,或实现类选择的任何因素进行选择。
* HandlerExecutionChain 对象中包含的处理器是 Object 类型的,而不是一个标记接口,所以处理器不会受到任何限制。
* 比如,可以编写一个 HandlerAdapter 允许使用另一个框架的处理器。
* 如果没有找到匹配的处理器,会返回 null,这并不是错误。
* DispatcherServlet 会查询所有注册的 HandlerMapping 以找到对应的匹配项,如果没有找到处理器,才会判定出错
* 内部的
* @param request 当前的HTTP请求
* @return 包含处理器对象和所有拦截器的 HandlerExecutionChain 对象,如果没找到,返回 null
* @throws 如果发生一个内部的错误,则抛出异常
*/
HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;

}

Ordered

接口。

Ordered 是一个接口,可以被可比较的对象实现,比如 Collection 类。

actual 实际

interpreted 解释执行,解读

prioritization 优先

实际的排序可以被解读为优先级,值越小,优先级越高,getOrder() 方法可以获取到具体的排序值。

此接口还有一个优先级的标记:PriorityOrdered,PriorityOrdered 对象表示的排序值始终在普通 Ordered对象表示的相同排序值之前起应用。

Consult 参考

precedence 优先权,位次

arbitrary 随意的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public interface Ordered {

/**
* 最高的优先级
*/
int HIGHEST_PRECEDENCE = Integer.MIN_VALUE;

/**
* 最低的优先级
*/
int LOWEST_PRECEDENCE = Integer.MAX_VALUE;


/**
* 获取此对象的排序值
* 值越小优先级越高,值越大优先级越低
* 相同的排序值,将导致受影响的元素随意的排序
*/
int getOrder();

}

PriorityOrdered

Ordered 接口的扩展,表示优先级排序:

PriorityOrdered 对象表示的顺序值始终在普通 Ordered 对象表示的相同顺序值之前应用。

这主要是一个专用接口,用于首先识别优先级对象尤为重要的对象,甚至不需要获取剩余的对象。一个典型的例子:Spring中的优先级后处理器 ApplicationContext。

注意: PriorityOrdered 后处理器 bean 在特殊阶段初始化,超过其他后处理器 bean。这巧妙地影响了它们的自动装配行为:它们只会针对不需要急切初始化类型匹配的 bean 进行自动装配。

extension 扩展

recognize 识别

phase 阶段

1
2
3
public interface PriorityOrdered extends Ordered {

}

Order

注解类,定义了排序值

1
2
3
4
5
6
7
8
9
10
11
12
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
@Documented
public @interface Order {

/**
* 排序值
* 默认值为Ordered.LOWEST_PRECEDENCE,最低优先级
* @see Ordered#getOrder()
*/
int value() default Ordered.LOWEST_PRECEDENCE;
}

value 是可选的,作用和 Ordered 接口中的排序值一样,value 越小,优先级越高,默认值是 Ordered.LOWEST_PRECEDENCE,最低优先级。

从 Spring 4.0 开始,Spring 中的很多组件都支持基于 Order 注解的排序,即使目标组件的排序值(目标类或 @Bean 方法)考虑的集合注入也是如此。虽然此类排序值可能会影响注入点的优先级,但请注意它们不会影响单例启动顺序,这是由依赖关系和 @DependsOn(影响运行时确定的依赖关系)声明确定的正交关注点。

从 Spring 4.1 开始,标准 Priority 注解可以用作排序方案中该注解的替代品。请注意, @Priority 当必须选择单个元素是,可能会有其他语义。具体参见 AnnotationAwareOrderComparator#getPriority

也可以通过 Ordered 接口基于每个实例确定排序值,允许配置确定的实例值而不是附加到特定类的硬编码值。

standard 标准

semantics 语义

Order 注解可以用于类注解、方法注解、字段注解。

OrderUtils

用于根据类型声明确定对象顺序的常规实用程序 , 用于处理 Spring 的 Order 注解和 Java 的 Priority 注解。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
public abstract class OrderUtils {

/**
* 优先级注解类型,使用 javax.annotation.Priority
*/
private static Class<? extends Annotation> priorityAnnotationType = null;

static {
try {
//兼容不同的 JDK 版本
priorityAnnotationType = (Class<? extends Annotation>)
ClassUtils.forName("javax.annotation.Priority", OrderUtils.class.getClassLoader());
}
catch (Throwable ex) {
// javax.annotation.Priority 无效,或者存在但是不可装载(JDK6)
}
}


/**
* 返回指定类型的排序值
* <p>Takes care of {@link Order @Order} and {@code @javax.annotation.Priority}.
* @param type 要处理的类型,即被注解的类
* @return 排序值,如果没有找到对应的类型,返回null
* @see #getPriority(Class)
*/
public static Integer getOrder(Class<?> type) {
return getOrder(type, null);
}

/**
* 返回指定类型的排序值,如果没有指定的类型,则返回默认的排序值
* <p>Takes care of {@link Order @Order} and {@code @javax.annotation.Priority}.
* @param type the type to handle
* @return the priority value, or the specified default order if none can be found
* @see #getPriority(Class)
*/
public static Integer getOrder(Class<?> type, Integer defaultOrder) {
//优先获取 Order 注解的值
Order order = AnnotationUtils.findAnnotation(type, Order.class);
if (order != null) {
return order.value();
}
// 如果没有声明 Order 注解, 返回 Priority 注解的值
Integer priorityOrder = getPriority(type);
if (priorityOrder != null) {
return priorityOrder;
}
// 如果两个注解都为 null, 则返回传入的默认排序值 defaultOrder
return defaultOrder;
}

/**
* 返回 {@code javax.annotation.Priority} 注解的值,如果类型上没有声明 Priority 注解,则返回 null
* @param type the type to handle
* @return the priority value if the annotation is declared, or {@code null} if none
*/
public static Integer getPriority(Class<?> type) {
if (priorityAnnotationType != null) {
// 获取类上面的 Priority 注解类对象
Annotation priority = AnnotationUtils.findAnnotation(type, priorityAnnotationType);
if (priority != null) {
// 获取注解类的 value 值
return (Integer) AnnotationUtils.getValue(priority);
}
}
//如果 Priority 注解没有加载,则直接返回 null
return null;
}

}

AbstractHandlerMapping

抽象类,实现了 HandlerMapping 和 Ordered 接口,同时继承了 WebApplicationObjectSupport 类。

支持排序,拥有一个默认的处理器,一系列处理器拦截器,包括路径模式映射的处理器拦截器。

该基础类不支持暴露 PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE。对此属性的支持取决于具体的子类,通常基于请求 URL 映射。

常用的子类有两个:AbstractHandlerMethodMapping 和 AbstractUrlHandlerMapping 。

AbstractHandlerMethodMapping 将具体的 Method 作为 Handler使用

AbstractUrlHandlerMapping 通过 URL 来进行匹配。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//默认的处理器
private Object defaultHandler;

//UrlPathHelper 对象,进行 URL 路径匹配
private UrlPathHelper urlPathHelper = new UrlPathHelper();

//路径匹配器
private PathMatcher pathMatcher = new AntPathMatcher();

//拦截器列表
private final List<Object> interceptors = new ArrayList<Object>();

//拦截器处理器列表
private final List<HandlerInterceptor> adaptedInterceptors = new ArrayList<HandlerInterceptor>();

//
private final UrlBasedCorsConfigurationSource globalCorsConfigSource = new UrlBasedCorsConfigurationSource();

//CORS处理器
private CorsProcessor corsProcessor = new DefaultCorsProcessor();

//排序值,指定HandlerMapping实现类的执行顺序,默认为 Ordered.LOWEST_PRECEDENCE,最低优先级
private int order = Ordered.LOWEST_PRECEDENCE;

实现了 HandlerMapping 接口的 getHandler 方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
//获取当前请求的处理器,如果没找到对应的处理器,则返回默认的处理器
Object handler = getHandlerInternal(request);
if (handler == null) {
handler = getDefaultHandler();
}
if (handler == null) {
return null;
}

// 返回的是Bean Name,则通过bean name创建处理器对象
if (handler instanceof String) {
String handlerName = (String) handler;
handler = getApplicationContext().getBean(handlerName);
}

//获取执行链
HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);

// CORS 跨越资源共享 判断是否为跨域请求 跨越请求需特殊处理
if (CorsUtils.isCorsRequest(request)) {
CorsConfiguration globalConfig = this.globalCorsConfigSource.getCorsConfiguration(request);
CorsConfiguration handlerConfig = getCorsConfiguration(handler, request);
CorsConfiguration config = (globalConfig != null ? globalConfig.combine(handlerConfig) : handlerConfig);
executionChain = getCorsHandlerExecutionChain(request, executionChain, config);
}
return executionChain;
}

getHandlerInternal 方法是一个抽象的方法,由具体的子类来实现,获取当前请求的处理器,如果没找到对应的处理器,则返回null。

1
protected abstract Object getHandlerInternal(HttpServletRequest request) throws Exception;

getDefaultHandler 方法即返回默认的处理器

1
2
3
public Object getDefaultHandler() {
return this.defaultHandler;
}

getHandlerExecutionChain 方法用于获取请求的执行链

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
//如果不存在,则创建一个HandlerExecutionChain对象
HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ?
(HandlerExecutionChain) handler : new HandlerExecutionChain(handler));

//获取请求的路径,相对路径,即Controller中方法配置的请求路径
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;
}

initApplicationContext() 方法,初始化时调用,初始化拦截器信息

HandlerInterceptor