1. 目录

[TOC]

2. 说明

springmvc的访问流程主要从DispatcherServlet#doDispatch开始的,
Tomcat:org.apache.catalina.ApplicationFilterChain#coreApplicationFilterChain() -> Java:javax.servlet.http.HttpServlet#service()-> springmvc:FrameworkServlet#Service -> springmvc:DistpatcherServlet#doDispatch()

3. 依赖分析

4. 源码分析

主要是从DistpatcherServlet#doDispathcer()开始正式进入流程

4.1. doDispathcer()

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
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);

//解析拦截器
mappedHandler = getHandler(processedRequest);
if (mappedHandler == null) {
noHandlerFound(processedRequest, response);
return;
}

//获取请求适配器
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

// 省略......

//执行拦截器链前处理返回了false,标识不再继续执行下去,返回退出
//自己实现的拦截器就在这里执行前置方法,重要的扩展点
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}

//执行请求
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

// 省略......

//执行拦截器链后处理
//自己实现的拦截器就在这里执行后置方法,重要的扩展点
mappedHandler.applyPostHandle(processedRequest, response, mv);
}
catch (Exception ex) {
dispatchException = ex;
}
catch (Throwable err) {
// 包装异常
dispatchException = new NestedServletException("Handler dispatch failed", err);
}
//组装返回数据(view或者数据)
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
catch (Exception ex) {
//拦截器后处理(释放ThreadLocal等)
//自己实现的拦截器就在这里执行完成方法,重要的扩展点
triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
}
catch (Throwable err) {
//拦截器后处理(释放ThreadLocal等)
//自己实现的拦截器就在这里执行完成方法,重要的扩展点
triggerAfterCompletion(processedRequest, response, mappedHandler,
new NestedServletException("Handler processing failed", err));
}
finally {
//......
}
}

4.1.1. getHandler()

1
2
3
4
5
6
7
8
9
10
11
12
//获取拦截器链
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
if (this.handlerMappings != null) {
for (HandlerMapping mapping : this.handlerMappings) {
HandlerExecutionChain handler = mapping.getHandler(request);
if (handler != null) {
return handler;
}
}
}
return null;
}

4.1.1.1. RequestMappingHandlerMapping#getHandler()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
//获取HandlerMethod
Object handler = getHandlerInternal(request);
//......

//获取拦截器链,并包装HanderMethod和Interceptors,主要是根据url来判断是否要加入对应的interceptor
HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);

//加入cors相关......
if (hasCorsConfigurationSource(handler) || CorsUtils.isPreFlightRequest(request)) {
//......
}

return executionChain;
}
4.1.1.1.1. ReqeuestMapingHandlerMapping#getHandlerInternal()获取请求方法封装

获取HandlerMethod,即Controller的封装,包括Class、method、paramters、result类型等

1
2
3
4
5
6
7
8
9
10
11
12
13
14
protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
//获取路径
String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
request.setAttribute(LOOKUP_PATH, lookupPath);
this.mappingRegistry.acquireReadLock();
try {
//获取到请求封装(这个里面可以自己看一下,主要就是封装Controller的封装,包括Class、method、paramters、result类型等)
HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);
return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null);
}
finally {
this.mappingRegistry.releaseReadLock();
}
}
4.1.1.1.2. getHandlerExecutionChain() 获取拦截器链
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ?
(HandlerExecutionChain) handler : new HandlerExecutionChain(handler));
//获取请求路径
String lookupPath = this.urlPathHelper.getLookupPathForRequest(request, LOOKUP_PATH);
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;
}

4.1.2. getHandlerAdapter()

1
2
3
4
5
6
7
8
9
10
11
12
13

//获取请求适配器 Object handler 一般为HandlerMethod
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
if (this.handlerAdapters != null) {
for (HandlerAdapter adapter : this.handlerAdapters) {
if (adapter.supports(handler)) {
return adapter;
}
}
}
throw new ServletException("No adapter for handler [" + handler +
"]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
}

4.1.2.1. HandlerAdapter#supports() 是否支持

对于RequestMappingHandlerAdaptor只要是HandlerMethod就是支持的,因为RequestMappingHandlerMapping生成的就是HandlerMethod,刚好对应

1
2
3
4
5
6
public final boolean supports(Object handler) {
return (handler instanceof HandlerMethod && supportsInternal((HandlerMethod) handler));
}
protected boolean supportsInternal(HandlerMethod handlerMethod) {
return true;
}

4.1.3. 执行请求 ha.handle() RequestMappingHandlerAdaptor

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
public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
return handleInternal(request, response, (HandlerMethod) handler);
}
protected ModelAndView handleInternal(HttpServletRequest request,
HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {

ModelAndView mav;
//检查是否支持的方法,GET POST等;检查是否需要session
checkRequest(request);

// ......省略session检查,不管是否需要session,都会进入到invokeHandlerMethod执行方法
mav = invokeHandlerMethod(request, response, handlerMethod);


if (!response.containsHeader(HEADER_CACHE_CONTROL)) {
if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {
applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers);
}
else {
prepareResponse(response);
}
}

return mav;
}
//执行的HandlerMethod方法
protected ModelAndView invokeHandlerMethod(HttpServletRequest request,
HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {

//构造Servlet请求
ServletWebRequest webRequest = new ServletWebRequest(request, response);
try {
//WebDataBinderFactory请求参数绑定相关,即请求的参数转化成对应的数据类型,如String->Integer
WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);
ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);

//将handlerMethod包装成ServletInvocableHandlerMethod,就new了一下,没啥可看的
ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);
//加入请求参数解析器,默认多达26种,见下方图片
if (this.argumentResolvers != null) {
invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);
}
//加入返回参数解析器,默认有15种,见下方图片
if (this.returnValueHandlers != null) {
invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);
}

//WebDataBinderFactory请求参数绑定相关,即请求的参数转化成对应的数据类型,如String->Integer
ModelAndViewContainer mavContainer = new ModelAndViewContainer();
mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request));
modelFactory.initModel(webRequest, mavContainer, invocableMethod);
mavContainer.setIgnoreDefaultModelOnRedirect(this.ignoreDefaultModelOnRedirect);

//......省略异步请求相关,有点复杂,我们直接看直接请求的
//**执行方法,重点**
invocableMethod.invokeAndHandle(webRequest, mavContainer);
if (asyncManager.isConcurrentHandlingStarted()) {
return null;
}

return getModelAndView(mavContainer, modelFactory, webRequest);
}
finally {
webRequest.requestCompleted();
}
}

请求参数解析器argumentResolvers
请求参数解析器

返回数据解析器returnValueHandlers
返回数据解析器

4.1.3.1. ServletInvocableHandlerMethod#invokeAndHandler() 执行请求方法

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
public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception {

//执行请求,并得到返回的数据,内部调用Controller方法
Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);
//设置响应码
setResponseStatus(webRequest);

//返回为空或有返回原因,设置之后返回,但是一般不走这两个,直接走后面handleReturnValue
if (returnValue == null) {
if (isRequestNotModified(webRequest) || getResponseStatus() != null || mavContainer.isRequestHandled()) {
disableContentCachingIfNecessary(webRequest);
mavContainer.setRequestHandled(true);
return;
}
}
else if (StringUtils.hasText(getResponseStatusReason())) {
mavContainer.setRequestHandled(true);
return;
}

mavContainer.setRequestHandled(false);
Assert.state(this.returnValueHandlers != null, "No return value handlers");
try {

//处理返回数据
this.returnValueHandlers.handleReturnValue(
returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
}
catch (Exception ex) {
//......异常抛出
}
}
4.1.3.1.1. invokeForRequest() 执行请求
1
2
3
4
5
6
7
public Object invokeForRequest(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,Object... providedArgs) throws Exception {
//解析请求的参数,如@RequestBody中的json,@RequestParam的参数列表,@PathVirable的参数
Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);

//执行方法
return doInvoke(args);
}
4.1.3.1.1.1. getMethodArgumentValues() 获取方法参数列表
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
protected Object[] getMethodArgumentValues(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception {

//获取方法参数列表,HandlerMethod封装的数据,直接拿的属性
MethodParameter[] parameters = getMethodParameters();
if (ObjectUtils.isEmpty(parameters)) {
return EMPTY_ARGS;
}

Object[] args = new Object[parameters.length];

//循环解析参数
for (int i = 0; i < parameters.length; i++) {
MethodParameter parameter = parameters[i];
parameter.initParameterNameDiscovery(this.parameterNameDiscoverer);
//这里匹配providedArgs中的值,若有对应类型的匹配,则赋值给args[i],一般providedArgs为空数组,所以这里返回为null,继续往下走
args[i] = findProvidedArgument(parameter, providedArgs);
if (args[i] != null) {
continue;
}

//通过resolvers来解析参数,绝大部分都是这里来解析,
//解析器见上方截图argumentResolvers,一般用的常用的就标注那几种
//ReqeustParamMethodArgumentResolver,PathVariableMethodArgumentResoulver,
//ReeustResponseMethodProcessor
//具体解析单个去分析
if (!this.resolvers.supportsParameter(parameter)) {
throw new IllegalStateException(formatArgumentError(parameter, "No suitable resolver"));
}
try {
args[i] = this.resolvers.resolveArgument(parameter, mavContainer, request, this.dataBinderFactory);
}
catch (Exception ex) {
//......抛异常,忽略
}
}
return args;
}
4.1.3.1.1.2. doInvoke()执行方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
protected Object doInvoke(Object... args) throws Exception {
//设置访问权限
ReflectionUtils.makeAccessible(getBridgedMethod());
try {
//反射执行方法,这里就执行到了Controller对应的方法了
return getBridgedMethod().invoke(getBean(), args);
}
catch (IllegalArgumentException ex) {
//......忽略异常
}
catch (InvocationTargetException ex) {
//......忽略异常
}
}

这里看完就得回到invokeAndHandler()中继续往下看了

4.1.3.1.2. returnValueHandlers.handleReturnValue() 处理返回数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType,
ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
//根据返回类型和返回值选择一个处理器
HandlerMethodReturnValueHandler handler = selectHandler(returnValue, returnType);
if (handler == null) {
throw new IllegalArgumentException("Unknown return value type: " + returnType.getParameterType().getName());
}
//执行返回数据组装方法,具体组装单独写
handler.handleReturnValue(returnValue, returnType, mavContainer, webRequest);
}
//选择返回组装处理器
private HandlerMethodReturnValueHandler selectHandler(@Nullable 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;
}

5. 总结

请求的主要流程在于

  • 理解拦截器链的生成和执行流程
  • 请求处理器和返回处理器的类型
  • 请求执行时的请求参数解析器和返回参数解析器有多个

6. 注意事项