springboot 请求响应处理流程

Tomcat 会把请求委托到
org.springframework.web.servlet.DispatcherServlet#doService

1
2
3
4
5
6
7
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
logRequest(request);

// 省略前面的代码
try {
doDispatch(request, response);
}

然后就是调用
org.springframework.web.servlet.DispatcherServlet#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
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {

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

try {
processedRequest = checkMultipart(request);
multipartRequestParsed = (processedRequest != request);

// 去获取处理器
// Determine handler for the current request.
mappedHandler = getHandler(processedRequest);
if (mappedHandler == null) {
noHandlerFound(processedRequest, response);
return;
}

// Determine handler adapter for the current request.
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

// Process last-modified header, if supported by the handler.
String method = request.getMethod();
boolean isGet = HttpMethod.GET.matches(method);
if (isGet || HttpMethod.HEAD.matches(method)) {
long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
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());

看下这里的逻辑

1
2
3
4
5
6
7
8
9
10
11
12
@Nullable
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;
}

可以看到有这些 HandlerMapping

而这里面就是前面提到过的
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
从这就能找到具体的 Handler
com.nicksxs.spbdemo.controller.DemoController#test()
这就是我简单的示例代码

1
2
3
4
5
6
7
8
9
@RequestMapping(value = "/test", method = RequestMethod.GET)
@ResponseBody
public DemoResponse test() {
String item = "{\"id\": 1, \"name\": \"nick\"}";
ParserConfig parserConfig = ParserConfig.getGlobalInstance();
parserConfig.propertyNamingStrategy = PropertyNamingStrategy.SnakeCase;
DemoResponse response = JSON.parseObject(item, DemoResponse.class, parserConfig);
return response;
}

下一步是再获取处理器的适配器,
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter

1
2
3
4
5
6
7
8
9
10
11
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");
}

正好这个适配器是调用的父类的 supports 方法

1
2
3
4
@Override
public final boolean supports(Object handler) {
return (handler instanceof HandlerMethod && supportsInternal((HandlerMethod) handler));
}

而我这个com.nicksxs.spbdemo.controller.DemoController#test()
就是个包装好的 HandlerMethod
然后就是调用 hahandle 方法,也是通过模板方法,实际调用的是
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter#handle

1
2
3
4
5
6
7
@Override
@Nullable
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

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
@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) {
mav = invokeHandlerMethod(request, response, handlerMethod);
}
}
else {
// No HttpSession available -> no mutex necessary
mav = invokeHandlerMethod(request, response, handlerMethod);
}
}
else {
// 是否要锁定 session,否则走到这
// No synchronization on session demanded at all...
mav = invokeHandlerMethod(request, response, handlerMethod);
}

继续调用
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#invokeHandlerMethod

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Nullable
protected ModelAndView invokeHandlerMethod(HttpServletRequest request,
HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {

ServletWebRequest webRequest = new ServletWebRequest(request, response);
try {
WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);
ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);

// 包装调用方法,
ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);
// 省略一部分非本次关注核心代码
// 然后是调用到这
invocableMethod.invokeAndHandle(webRequest, mavContainer);
if (asyncManager.isConcurrentHandlingStarted()) {
return null;
}

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

稍微再看一眼
第一步是
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#createInvocableHandlerMethod

1
2
3
protected ServletInvocableHandlerMethod createInvocableHandlerMethod(HandlerMethod handlerMethod) {
return new ServletInvocableHandlerMethod(handlerMethod);
}

第二步是
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod#ServletInvocableHandlerMethod(org.springframework.web.method.HandlerMethod)

1
2
3
   public ServletInvocableHandlerMethod(HandlerMethod handlerMethod) {
super(handlerMethod);
}

第三步是
org.springframework.web.method.support.InvocableHandlerMethod#InvocableHandlerMethod(org.springframework.web.method.HandlerMethod)

1
2
3
   public InvocableHandlerMethod(HandlerMethod handlerMethod) {
super(handlerMethod);
}

第四步是
org.springframework.web.method.HandlerMethod#HandlerMethod(org.springframework.web.method.HandlerMethod)

1
2
3
4
5
6
7
8
9
10
11
12
13
protected HandlerMethod(HandlerMethod handlerMethod) {
Assert.notNull(handlerMethod, "HandlerMethod is required");
this.bean = handlerMethod.bean;
this.beanFactory = handlerMethod.beanFactory;
this.beanType = handlerMethod.beanType;
this.method = handlerMethod.method;
this.bridgedMethod = handlerMethod.bridgedMethod;
this.parameters = handlerMethod.parameters;
this.responseStatus = handlerMethod.responseStatus;
this.responseStatusReason = handlerMethod.responseStatusReason;
this.description = handlerMethod.description;
this.resolvedFromHandlerMethod = handlerMethod.resolvedFromHandlerMethod;
}

这是个继承关系,一直调用到最顶层的父类的构造方法,其实就是拷贝,然后继续调用
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod#invokeAndHandle

1
2
3
4
5
6
7
public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer,
Object... providedArgs) throws Exception {

// 调用请求
Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);
// 稍微忽略下后面的代码
}

继续调用
org.springframework.web.method.support.InvocableHandlerMethod#invokeForRequest

1
2
3
4
5
6
7
8
9
10
@Nullable
public Object invokeForRequest(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,
Object... providedArgs) throws Exception {

Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);
if (logger.isTraceEnabled()) {
logger.trace("Arguments: " + Arrays.toString(args));
}
return doInvoke(args);
}

来到了最核心处
org.springframework.web.method.support.InvocableHandlerMethod#doInvoke

1
2
3
4
5
6
7
8
9
10
11
@Nullable
protected Object doInvoke(Object... args) throws Exception {
Method method = getBridgedMethod();
ReflectionUtils.makeAccessible(method);
try {
if (KotlinDetector.isSuspendingFunction(method)) {
return CoroutinesUtils.invokeSuspendingFunction(method, getBean(), args);
}
// 会走到这里,获取到 bean,而这个 bean 就是前面构造方法里赋值的,最开始被放在 handler 里面,然后调用方法
return method.invoke(getBean(), args);
}