springboot 请求响应处理流程
Tomcat 会把请求委托到org.springframework.web.servlet.DispatcherServlet#doService
1
2
3
4
5
6
7protected 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
38protected 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
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
从这就能找到具体的 Handlercom.nicksxs.spbdemo.controller.DemoController#test()
这就是我简单的示例代码1
2
3
4
5
6
7
8
9
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
11protected 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
public final boolean supports(Object handler) {
return (handler instanceof HandlerMethod && supportsInternal((HandlerMethod) handler));
}
而我这个com.nicksxs.spbdemo.controller.DemoController#test()
就是个包装好的 HandlerMethod
然后就是调用 ha
的 handle
方法,也是通过模板方法,实际调用的是org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter#handle
1
2
3
4
5
6
7
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
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
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
3protected 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
13protected 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
7public 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
public Object invokeForRequest(NativeWebRequest request, 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
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);
}