Spring Web模块

Spring Web模块

关系

1
2
3
4
5
6
7
8
9
Spring WebSpring Web MVCSpring WebFluxSpring框架中用于构建Web应用程序的不同模块。它们之间的关系如下:

1. Spring WebSpring Web是一个顶级模块,它提供了通用的Web开发功能和抽象。它包含了一些通用的Web特性和工具,如HTTP请求和响应的处理、Servlet API的封装、静态资源处理等。Spring Web本身不提供具体的Web框架实现,而是为其他Web框架(如Spring Web MVCSpring WebFlux)提供基础支持。

2. Spring Web MVCSpring Web MVC是基于Servlet API的传统的Web框架,它是Spring框架中最早的Web框架。它使用了经典的ServletJSP技术,通过控制器、视图解析器和模型来构建Web应用程序。Spring Web MVC提供了一种基于模型-视图-控制器(MVC)的架构模式,用于处理和响应HTTP请求。它使用注解或XML配置来定义请求映射、处理器方法和视图解析器等。

3. Spring WebFluxSpring WebFluxSpring框架中的响应式Web框架,它是在Spring 5中引入的。与传统的基于ServletWeb框架不同,Spring WebFlux使用了非阻塞I/O模型,基于Reactor库实现了响应式编程。它提供了一种函数式和反应式的编程模型,适用于高吞吐量和低延迟的应用程序。Spring WebFlux支持两种编程模型:基于注解的WebFlux和基于函数式的WebFlux。它使用路由函数来定义请求路由和处理器函数来处理请求。

总结起来,Spring Web是一个通用的Web开发模块,提供了基础的Web功能和抽象。Spring Web MVC是基于Servlet API的传统Web框架,使用MVC架构模式来构建Web应用程序。Spring WebFluxSpring框架中的响应式Web框架,使用非阻塞I/O和响应式编程模型来构建高性能的Web应用程序。

官方文档

Web on Servlet Stack (spring.io)

在这里插入图片描述

MVC容器关系图

web容器

Restful风格

idempotent : 幂等

img

业务

自定义全局异常处理

SpringMVC全局异常处理 - GordonDicaprio - 博客园 (cnblogs.com)

Spring Web MVC

Web on Servlet Stack (spring.io)

img

流程

–SpringMVC执行流程:

1
2
3
4
5
6
7
8
9
10
11
01、用户发送出请求被前端控制器DispatcherServlet拦截进行处理。
02、DispatcherServlet收到请求调用HandlerMapping(处理器映射器)。
03、HandlerMapping找到具体的处理器(查找xml配置或注解配置),生成处理器对象及处理器拦截器(如果有),再一起返回给DispatcherServlet。
04、DispatcherServlet调用HandlerAdapter(处理器适配器)。
05、HandlerAdapter经过适配调用具体的处理器(Handler/Controller)。
06、Controller执行完成返回ModelAndView对象。
07、HandlerAdapter将Controller执行结果ModelAndView返回给DispatcherServlet。
08、DispatcherServlet将ModelAndView传给ViewReslover(视图解析器)。
09、ViewReslover解析ModelAndView后返回具体View(视图)给DispatcherServlet。
10、DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。
11、DispatcherServlet响应View给用户。

–涉及组件分析:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1、前端控制器DispatcherServlet(不需要程序员开发)由框架提供,在web.xml中配置。
作用:接收请求,响应结果,相当于转发器,中央处理器。

2、处理器映射器HandlerMapping(不需要程序员开发)由框架提供。
作用:根据请求的url查找Handler(处理器/Controller),可以通过XML和注解方式来映射。

3、处理器适配器HandlerAdapter(不需要程序员开发)由框架提供。
作用:按照特定规则(HandlerAdapter要求的规则)去执行Handler中的方法。

4、处理器Handler(也称之为Controller,需要程序员开发)
注意:编写Handler时按照HandlerAdapter的要求去做,这样适配器才可以去正确执行Handler。
作用:接受用户请求信息,调用业务方法处理请求,也称之为后端控制器。

5、视图解析器ViewResolver(不需要程序员开发)由框架提供。
作用:进行视图解析,把逻辑视图解析成真正的物理视图。
SpringMVC框架支持多种View视图技术,包括:jstlView、freemarkerView、ThymeleafView等。

6、视图View(需要工程师开发)
作用:把数据展现给用户的页面
View是一个接口,实现类支持不同的View技术(jsp、freemarker、pdf等)

请求路径url-@RequestMapping

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
@RequestMapping注解在Spring Web中由RequestMappingHandlerMapping类进行解析。

RequestMappingHandlerMapping是Spring MVC框架中的一个处理器映射器(HandlerMapping),负责将请求映射到对应的处理器方法(Controller方法)。

具体的解析过程如下:

1. 组件扫描:在Spring启动时,会进行组件扫描,扫描应用程序中被@Controller注解标记的控制器类。

2. 注册为Bean:被扫描到的@Controller类会被实例化并注册为Spring管理的Bean。

3. 注册RequestMappingHandlerMapping:RequestMappingHandlerMapping会被自动注册到Spring MVC的上下文中。它会在Spring MVC的初始化过程中被加载,并处理请求映射。

4. 解析@RequestMapping注解:RequestMappingHandlerMapping会扫描所有被@Controller注解标记的类和方法,解析其中的@RequestMapping注解。

- 类级别的@RequestMapping注解:表示该控制器类处理的URL路径的基础路径。

- 方法级别的@RequestMapping注解:表示该方法处理的URL路径。

5. 构建请求映射:RequestMappingHandlerMapping会根据类级别和方法级别的@RequestMapping注解的值,构建请求映射规则。

- 类级别的@RequestMapping注解的值会与方法级别的@RequestMapping注解的值进行拼接,形成最终的请求路径。

- 请求路径还可以使用占位符、正则表达式等进行更灵活的匹配。

6. 注册请求映射规则:RequestMappingHandlerMapping会将解析得到的请求映射规则注册到Spring MVC的请求映射表中。

- 请求映射表是一个Map结构,将请求路径与对应的处理器方法进行映射。

7. 请求分发:当请求到达时,DispatcherServlet会调用RequestMappingHandlerMapping的方法来根据请求路径匹配最合适的处理器方法。

- RequestMappingHandlerMapping会根据请求路径在请求映射表中查找匹配的处理器方法。

- 如果找到匹配的处理器方法,就会返回对应的处理器方法。

- 如果找不到匹配的处理器方法,会返回404错误。

总结起来,@RequestMapping注解由RequestMappingHandlerMapping类进行解析。RequestMappingHandlerMapping会扫描被@Controller注解标记的类和方法,解析其中的@RequestMapping注解,并构建请求映射规则。这些规则会被注册到Spring MVC的请求映射表中,用于将请求分发给对应的处理器方法。

–根据以上分析,SpringMVC需要程序员完成的工作有三个:

【1】配置前端控制器DispatcherServlet。

RequestMappingHandlerMapping 解析 路径信息、controller到路径信息,根据路径找到合适的处理方法

【2】开发后端控制器Handler/Controller。

【3】开发视图View。

Servlet

servlet详情

1
包含tomcat 的执行链:request从stream变为servletRequest的步骤吗,调用doService()前的容器执行链,wrapper的过滤器执行

DispatcherServlet ## doService()

1
2
3
4
DispatcherServlet ## doService() ## doDispatcher() 
-> getHanlder() —> handleMapping.getHandler()
-> getHandlerAdapter() ( HandlerAdapter.support())
-> preHandler() -> handlerAdapther.handler() -> postHandler()

DispatcherServlet

image-20230421080039491

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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
public class DispatcherServlet extends FrameworkServlet {
private static Properties defaultStrategies;
private boolean detectAllHandlerMappings = true;
private boolean detectAllHandlerAdapters = true;
private boolean detectAllHandlerExceptionResolvers = true;
private boolean detectAllViewResolvers = true;
private boolean throwExceptionIfNoHandlerFound = false;
private boolean cleanupAfterInclude = true;
// multipart -- 解析 multipart/content-type -- 文件上传,Request转为MultipartHttpServletRequest
private MultipartResolver multipartResolver;
// 本地化处理 -- 包括时间区域time zone(从head、session、cookie中取得)
private LocaleResolver localeResolver;
// model view 主题解析
private ThemeResolver themeResolver;
// HandlerMapping 用于获取处理请求的Handler的 HandlerExecutionChain
private List<HandlerMapping> handlerMappings;
// 适配Handler的处理器
private List<HandlerAdapter> handlerAdapters;
// 异常处理器 -- 可以配置处理器链 -- @ExceptionHandler 注解的处理链路
private List<HandlerExceptionResolver> handlerExceptionResolvers;
//
private RequestToViewNameTranslator viewNameTranslator;
// redirect时用于参数的传递 FlashAttributes
private FlashMapManager flashMapManager;
// 视图解析器
private List<ViewResolver> viewResolvers;
private boolean parseRequestPath;
// 重写refresh的方法
protected void onRefresh(ApplicationContext context) {
this.initStrategies(context);
}
// 初始化 web参数
protected void initStrategies(ApplicationContext context) {
this.initMultipartResolver(context);
this.initLocaleResolver(context);
this.initThemeResolver(context);
this.initHandlerMappings(context);
this.initHandlerAdapters(context);
this.initHandlerExceptionResolvers(context);
this.initRequestToViewNameTranslator(context);
this.initViewResolvers(context);
this.initFlashMapManager(context);
}
// web容器 (Tomcat)进行管理,调用
// doService -- 容器wrapper 的pipeline的最后一个value出进行 调用doService() 方法,
// 并且在此之前执行了过滤器链
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
this.logRequest(request);
Map<String, Object> attributesSnapshot = null;
if (WebUtils.isIncludeRequest(request)) {
attributesSnapshot = new HashMap();
Enumeration attrNames = request.getAttributeNames();

label116:
while(true) {
String attrName;
do {
if (!attrNames.hasMoreElements()) {
break label116;
}

attrName = (String)attrNames.nextElement();
} while(!this.cleanupAfterInclude && !attrName.startsWith("org.springframework.web.servlet"));

attributesSnapshot.put(attrName, request.getAttribute(attrName));
}
}

request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.getWebApplicationContext());
request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver);
request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver);
request.setAttribute(THEME_SOURCE_ATTRIBUTE, this.getThemeSource());
if (this.flashMapManager != null) {
FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate(request, response);
if (inputFlashMap != null) {
request.setAttribute(INPUT_FLASH_MAP_ATTRIBUTE, Collections.unmodifiableMap(inputFlashMap));
}

request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());
request.setAttribute(FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager);
}

RequestPath previousRequestPath = null;
if (this.parseRequestPath) {
previousRequestPath = (RequestPath)request.getAttribute(ServletRequestPathUtils.PATH_ATTRIBUTE);
ServletRequestPathUtils.parseAndCache(request);
}

try { // 分发入口
this.doDispatch(request, response);
} finally {
if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted() && attributesSnapshot != null) {
this.restoreAttributesAfterInclude(request, attributesSnapshot);
}

if (this.parseRequestPath) {
ServletRequestPathUtils.setParsedRequestPath(previousRequestPath, request);
}

}

}


// 分发逻辑
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
boolean multipartRequestParsed = false;
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

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

try {
processedRequest = this.checkMultipart(request);
multipartRequestParsed = processedRequest != request;
// 通过handlerMapping 的 getHandler() 方法获取 HandlerExecutionChain
mappedHandler = this.getHandler(processedRequest);
if (mappedHandler == null) {
this.noHandlerFound(processedRequest, respons
e);
return;
}
// 通过HandlerAdapter的 support() 从适配器链中获取对应的处理 adapter
// 一般为RequestMappingHandlerAdapter
HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
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;
}
}
// HandlerExecutionChain方法,循环调用拦截器的preHandle()
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
// HandlerAdapter的方法 handler()
// ## mappedHandler.getHandler(),获取执行链的封装的Handler方法
// 默认的Handler为HandlerMethod -- AbstractHandlerMethodAdapter的support方法
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}

this.applyDefaultViewName(processedRequest, mv);
// HandlerExecutionChain方法,循环调用拦截器的postHandle()
mappedHandler.applyPostHandle(processedRequest, response, mv);
} catch (Exception ex) {
// 捕捉全局异常Exception
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);
}
// 处理结果返回结果 --- 异常处理 HandlerExceptionResolver //
this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException);
catch (Exception var22) {
// HandlerExecutionChain方法,循环调用拦截器的afterCompletion()
this.triggerAfterCompletion(processedRequest, response, mappedHandler, var22);
} catch (Throwable var23) {
this.triggerAfterCompletion(processedRequest, response, mappedHandler, new NestedServletException("Handler processing failed", var23));
} finally {
if (asyncManager.isConcurrentHandlingStarted()) {
if (mappedHandler != null) {
// HandlerExecutionChain方法,循环调用 异步的handler
mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
}
} else if (multipartRequestParsed) {
this.cleanupMultipart(processedRequest);
}

}
}

}


Dispathcer 注册 HandlerExceptionresolver

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 initHandlerExceptionResolvers(ApplicationContext context) {
this.handlerExceptionResolvers = null;

if (this.detectAllHandlerExceptionResolvers) {
// Find all HandlerExceptionResolvers in the ApplicationContext, including ancestor contexts.
Map<String, HandlerExceptionResolver> matchingBeans = BeanFactoryUtils
.beansOfTypeIncludingAncestors(context, HandlerExceptionResolver.class, true, false);
if (!matchingBeans.isEmpty()) {
this.handlerExceptionResolvers = new ArrayList<>(matchingBeans.values());
// We keep HandlerExceptionResolvers in sorted order.
AnnotationAwareOrderComparator.sort(this.handlerExceptionResolvers);
}
}
else {
try {
HandlerExceptionResolver her =
context.getBean(HANDLER_EXCEPTION_RESOLVER_BEAN_NAME, HandlerExceptionResolver.class);
this.handlerExceptionResolvers = Collections.singletonList(her);
}
catch (NoSuchBeanDefinitionException ex) {
// Ignore, no HandlerExceptionResolver is fine too.
}
}

// Ensure we have at least some HandlerExceptionResolvers, by registering
// default HandlerExceptionResolvers if no other resolvers are found.
if (this.handlerExceptionResolvers == null) {
this.handlerExceptionResolvers = getDefaultStrategies(context, HandlerExceptionResolver.class);
if (logger.isTraceEnabled()) {
logger.trace("No HandlerExceptionResolvers declared in servlet '" + getServletName() +
"': using default strategies from DispatcherServlet.properties");
}
}
}

Dispatcher结果处理

Dispatcher ## doDispatcher() ## processDispatchResult(). ## processHandlerException()

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
87
88
89
90
/*Handle the result of handler selection and handler invocation, which is
* either a ModelAndView or an Exception to be resolved to a ModelAndView.
a ModelAndView // an Exception to be resolved to a ModelAndView
*/
private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,
@Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv,
@Nullable Exception exception) throws Exception {

boolean errorView = false;

if (exception != null) {
if (exception instanceof ModelAndViewDefiningException) {
logger.debug("ModelAndViewDefiningException encountered", exception);
mv = ((ModelAndViewDefiningException) exception).getModelAndView();
}
else {
// 用 @ExceptionHandler 的handler处理异常
Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);
mv = processHandlerException(request, response, handler, exception);
errorView = (mv != null);
}
}

// Did the handler return a view to render?
if (mv != null && !mv.wasCleared()) {
render(mv, request, response);
if (errorView) {
WebUtils.clearErrorRequestAttributes(request);
}
}
else {
if (logger.isTraceEnabled()) {
logger.trace("No view rendering, null ModelAndView returned.");
}
}

if (WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
// Concurrent handling started during a forward
return;
}

if (mappedHandler != null) {
// Exception (if any) is already handled..
mappedHandler.triggerAfterCompletion(request, response, null);
}
}


@Nullable
protected ModelAndView processHandlerException(HttpServletRequest request, HttpServletResponse response,
@Nullable Object handler, Exception ex) throws Exception {

// Success and error responses may use different content types
request.removeAttribute(HandlerMapping.PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE);

// Check registered HandlerExceptionResolvers...
ModelAndView exMv = null;
if (this.handlerExceptionResolvers != null) {
for (HandlerExceptionResolver resolver : this.handlerExceptionResolvers) {
// 调用 解析exception
exMv = resolver.resolveException(request, response, handler, ex);
if (exMv != null) {
break;
}
}
}
if (exMv != null) {
if (exMv.isEmpty()) {
request.setAttribute(EXCEPTION_ATTRIBUTE, ex);
return null;
}
// We might still need view name translation for a plain error model...
if (!exMv.hasView()) {
String defaultViewName = getDefaultViewName(request);
if (defaultViewName != null) {
exMv.setViewName(defaultViewName);
}
}
if (logger.isTraceEnabled()) {
logger.trace("Using resolved error view: " + exMv, ex);
}
else if (logger.isDebugEnabled()) {
logger.debug("Using resolved error view: " + exMv);
}
WebUtils.exposeErrorRequestAttributes(request, ex, getServletName());
return exMv;
}

throw ex;
}

HandlerExceptionResolver

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

/**
* Try to resolve the given exception that got thrown during handler execution,
* returning a {@link ModelAndView} that represents a specific error page if appropriate.
* <p>The returned {@code ModelAndView} may be {@linkplain ModelAndView#isEmpty() empty}
* to indicate that the exception has been resolved successfully but that no view
* should be rendered, for instance by setting a status code.
* @param request current HTTP request
* @param response current HTTP response
* @param handler the executed handler, or {@code null} if none chosen at the
* time of the exception (for example, if multipart resolution failed)
* @param ex the exception that got thrown during handler execution
* @return a corresponding {@code ModelAndView} to forward to,
* or {@code null} for default processing in the resolution chain
*/
@Nullable
ModelAndView resolveException(
HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex);

}

HandlerMapping

1
2
3
4
5
6
7
8
9
public interface HandlerMapping {
String BEST_MATCHING_HANDLER_ATTRIBUTE = HandlerMapping.class.getName() + ".bestMatchingHandler";
// 是否使用路径匹配
default boolean usesPathPatterns() {
return false;
}
// 通过请求 获取拦截器执行链
HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;
}

HandlerExecutionChain

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
// HandlerExecutionChain
public class HandlerExecutionChain {
// HandlerMethod --
private final Object handler;
// 拦截器执行链
private final List<HandlerInterceptor> interceptorList;
private int interceptorIndex;
// doDispather() ## applyPreHandle, applyPostHandle, triggerAfterCompletion
boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
for(int i = 0; i < this.interceptorList.size(); this.interceptorIndex = i++) {
HandlerInterceptor interceptor = (HandlerInterceptor)this.interceptorList.get(i);
// preHandler ---返回false,执行链结束
if (!interceptor.preHandle(request, response, this.handler)) {
this.triggerAfterCompletion(request, response, (Exception)null);
return false;
}
}

return true;
}

void applyPostHandle(HttpServletRequest request, HttpServletResponse response, @Nullable ModelAndView mv) throws Exception {
for(int i = this.interceptorList.size() - 1; i >= 0; --i) {
HandlerInterceptor interceptor = (HandlerInterceptor)this.interceptorList.get(i);
interceptor.postHandle(request, response, this.handler, mv);
}

}

void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex) {
for(int i = this.interceptorIndex; i >= 0; --i) {
HandlerInterceptor interceptor = (HandlerInterceptor)this.interceptorList.get(i);
try { // 执行链提前结束时 或者 抛出异常时调用
interceptor.afterCompletion(request, response, this.handler, ex);
} catch (Throwable var7) {
logger.error("HandlerInterceptor.afterCompletion threw exception", var7);
}
}
}
public Object getHandler() {
return this.handler;
}
}

HandlerInterceptor

拦截器执行链

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public interface HandlerInterceptor {
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return true;
}
// the response is written and committed within the HandlerAdapter and before postHandle
// too late to make any changes to the response
// you can implement ResponseBodyAdvice and either declare it as an Controller Advice bean or configure it directly on RequestMappingHandlerAdapter.

// 执行在response提交ModelAndView之后,不建议通过其修改response
// 可以通过ResponseBodyAdvice接口,ControllerAdvice, RequestMappingHandlerAdapter来修改response
default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
}
// 一般不使用 -- 完整请求结束之后,执行链抛出异常或者return false时调用
default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
}
}

AsyncHandlerInterceptor

1
2
3
4
5
public interface AsyncHandlerInterceptor extends HandlerInterceptor {
// 异步的执行链处理器,doDispather()最终视条件调用
default void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
}
}

image-20230424105538987

**DispatcherServlet ## doDispatcher() **

## HandlerAdapther.handler()

1
2
3
4
5
6
7
8
9
10
11
HandlerAdapter ## handle()
AbstractHandlerMethodAdapter ## handle() ## handleInternal()
RequestMappingHandlerAdapter ## handleInternal() ## invokeHandlerMethod()
## ModelAndViewContainer mavContainer = new ModelAndViewContainer(); // 封装ModelAndViewContainer
## invocableMethod.invokeAndHandle(webRequest, mavContainer, new Object[0]);
## 方法调用 + 封装返回返回值
ServletInvocableHandlerMethod ## invokeAndHandle()
## invokeForRequest() // 调用具体的方法 -- controller方法
HandlerMethodReturnValueHandlerComposite ## handleReturnValue() // 返回值处理
HandlerMethodReturnValueHandler ## handleReturnValue()

HandlerAdapter

1
2
3
4
5
6
7
8
9
10
public interface HandlerAdapter {
boolean supports(Object handler);

@Nullable
ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;

/** @deprecated */
@Deprecated
long getLastModified(HttpServletRequest request, Object handler);
}

AbstractHandlerMethodAdapter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public abstract class AbstractHandlerMethodAdapter extends WebContentGenerator implements HandlerAdapter, Ordered {
private int order = 2147483647;
public void setOrder(int order) {
this.order = order;
}
// HandlerMethod && supportsInternal() ---继承父类,调用子类实现
public final boolean supports(Object handler) {
return handler instanceof HandlerMethod && this.supportsInternal((HandlerMethod)handler);
}
// 子类实现
protected abstract boolean supportsInternal(HandlerMethod handlerMethod);

// 继承父类,调用子类实现
public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return this.handleInternal(request, response, (HandlerMethod)handler);
}
// 子类实现
protected abstract ModelAndView handleInternal(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception;

RequestMappingHandlerAdapter

参数

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
public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter implements BeanFactoryAware, InitializingBean {
private static final boolean shouldIgnoreXml = SpringProperties.getFlag("spring.xml.ignore");
public static final MethodFilter INIT_BINDER_METHODS = (method) -> {
return AnnotatedElementUtils.hasAnnotation(method, InitBinder.class);
};
public static final MethodFilter MODEL_ATTRIBUTE_METHODS = (method) -> {
return !AnnotatedElementUtils.hasAnnotation(method, RequestMapping.class) && AnnotatedElementUtils.hasAnnotation(method, ModelAttribute.class);
};
// 处理方法Handler(controller)的方法参数解析器 链
private List<HandlerMethodArgumentResolver> customArgumentResolvers;
// 解析参数
private HandlerMethodArgumentResolverComposite argumentResolvers;
// 解析@InitBinder绑定的参数
private HandlerMethodArgumentResolverComposite initBinderArgumentResolvers;
// 方法返回值处理链
private List<HandlerMethodReturnValueHandler> customReturnValueHandlers;
// 方法返回值处理
private HandlerMethodReturnValueHandlerComposite returnValueHandlers;
// 模型和视图解析器
private List<ModelAndViewResolver> modelAndViewResolvers;
// 内容协商管理器
private ContentNegotiationManager contentNegotiationManager = new ContentNegotiationManager();
// http消息转化器 -- 像编码统一
private List<HttpMessageConverter<?>> messageConverters = new ArrayList(4);
// requestResponseBodyAdvice ---
private final List<Object> requestResponseBodyAdvice = new ArrayList();
//
private WebBindingInitializer webBindingInitializer;
// 线程池
private AsyncTaskExecutor taskExecutor = new SimpleAsyncTaskExecutor("MvcAsync");
// 异步请求的时间限制
private Long asyncRequestTimeout;
//
private CallableProcessingInterceptor[] callableInterceptors = new CallableProcessingInterceptor[0];
private DeferredResultProcessingInterceptor[] deferredResultInterceptors = new DeferredResultProcessingInterceptor[0];
private ReactiveAdapterRegistry reactiveAdapterRegistry = ReactiveAdapterRegistry.getSharedInstance();
private boolean ignoreDefaultModelOnRedirect = false;
private int cacheSecondsForSessionAttributeHandlers = 0;
private boolean synchronizeOnSession = false;
private SessionAttributeStore sessionAttributeStore = new DefaultSessionAttributeStore();
private ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
@Nullable
private ConfigurableBeanFactory beanFactory;
// SessionAttributesHandler ---处理器的缓存
private final Map<Class<?>, SessionAttributesHandler> sessionAttributesHandlerCache = new ConcurrentHashMap(64);
// @InitBinder 方法缓存
private final Map<Class<?>, Set<Method>> initBinderCache = new ConcurrentHashMap(64);
// 对应的 ControllerAdviceBean 与 他之下的 @InitBinder
private final Map<ControllerAdviceBean, Set<Method>> initBinderAdviceCache = new LinkedHashMap();
// @ModelAttribute 方法混村
private final Map<Class<?>, Set<Method>> modelAttributeCache = new ConcurrentHashMap(64);
// 对应的 ControllerAdviceBean 与 他之下的 @ModelAttribute
private final Map<ControllerAdviceBean, Set<Method>> modelAttributeAdviceCache = new LinkedHashMap();

初始化

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
    // 继承接口,实现初始化方法,同ExceptionHandlerMethodResolver
public void afterPropertiesSet() {
// 初始化 ControllerAdvice注解的属性缓存
this.initControllerAdviceCache();
// 处理链
List handlers;
// 初始化参数解析器
if (this.argumentResolvers == null) {
handlers = this.getDefaultArgumentResolvers();
this.argumentResolvers = (new HandlerMethodArgumentResolverComposite()).addResolvers(handlers);
}
// 初始化 @InitBinder注解的参数解析器
if (this.initBinderArgumentResolvers == null) {
handlers = this.getDefaultInitBinderArgumentResolvers();
this.initBinderArgumentResolvers = (new HandlerMethodArgumentResolverComposite()).addResolvers(handlers);
}
// 初始化返回值处理器
if (this.returnValueHandlers == null) {
handlers = this.getDefaultReturnValueHandlers();
this.returnValueHandlers = (new HandlerMethodReturnValueHandlerComposite()).addHandlers(handlers);
}
}

// 00000000000000000000000000000000000000
public static final MethodFilter INIT_BINDER_METHODS = (method) -> {
return AnnotatedElementUtils.hasAnnotation(method, InitBinder.class);
};
public static final MethodFilter MODEL_ATTRIBUTE_METHODS = (method) -> {
return !AnnotatedElementUtils.hasAnnotation(method, RequestMapping.class) && AnnotatedElementUtils.hasAnnotation(method, ModelAttribute.class);
};

// 初始化 @ControllerAdvice注解 缓存
private void initControllerAdviceCache() {
if (this.getApplicationContext() != null) {
List<ControllerAdviceBean> adviceBeans = ControllerAdviceBean.findAnnotatedBeans(this.getApplicationContext());
List<Object> requestResponseBodyAdviceBeans = new ArrayList();
Iterator var3 = adviceBeans.iterator();

while(var3.hasNext()) {
ControllerAdviceBean adviceBean = (ControllerAdviceBean)var3.next();
Class<?> beanType = adviceBean.getBeanType();
if (beanType == null) {
throw new IllegalStateException("Unresolvable type for ControllerAdviceBean: " + adviceBean);
}
// MODEL_ATTRIBUTE_METHODS -- @ModelAttribute ModelAttribute.class
Set<Method> attrMethods = MethodIntrospector.selectMethods(beanType, MODEL_ATTRIBUTE_METHODS);
// 将@ModelAttribute的bean方法加入 缓存
if (!attrMethods.isEmpty()) {
this.modelAttributeAdviceCache.put(adviceBean, attrMethods);
}
// INIT_BINDER_METHODS ---@InitBinder InitBinder.class
Set<Method> binderMethods = MethodIntrospector.selectMethods(beanType, INIT_BINDER_METHODS);
// 将@InitBinder的bean方法加入缓存
if (!binderMethods.isEmpty()) {
this.initBinderAdviceCache.put(adviceBean, binderMethods);
}
// 判断是否时 可分配到 --- RequestBodyAdvice
if (RequestBodyAdvice.class.isAssignableFrom(beanType) || ResponseBodyAdvice.class.isAssignableFrom(beanType)) {
requestResponseBodyAdviceBeans.add(adviceBean);
}
}

if (!requestResponseBodyAdviceBeans.isEmpty()) {
this.requestResponseBodyAdvice.addAll(0, requestResponseBodyAdviceBeans);
}
}
}

RequestBodyAdvice
1
2
3
4
5
6
7
8
9
10
public interface RequestBodyAdvice {
boolean supports(MethodParameter methodParameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType);

HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) throws IOException;

Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType);

@Nullable
Object handleEmptyBody(@Nullable Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType);
}

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
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
87
    // 重写父类的方法
protected ModelAndView handleInternal(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
this.checkRequest(request);
ModelAndView mav;
if (this.synchronizeOnSession) {
HttpSession session = request.getSession(false);
if (session != null) {
Object mutex = WebUtils.getSessionMutex(session);
synchronized(mutex) { // 真正方法 handler 的执行
mav = this.invokeHandlerMethod(request, response, handlerMethod);
}
} else { // 真正方法 handler 的执行
mav = this.invokeHandlerMethod(request, response, handlerMethod);
}
} else { // 真正方法 handler 的执行
mav = this.invokeHandlerMethod(request, response, handlerMethod);
}

if (!response.containsHeader("Cache-Control")) {
if (this.getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {
this.applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers);
} else {
this.prepareResponse(response);
}
}

return mav;
}
// 具体方法执行
protected ModelAndView invokeHandlerMethod(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
ServletWebRequest webRequest = new ServletWebRequest(request, response);

ModelAndView var15;
try {
WebDataBinderFactory binderFactory = this.getDataBinderFactory(handlerMethod);
// 获取 Global controller advice method
ModelFactory modelFactory = this.getModelFactory(handlerMethod, binderFactory);
ServletInvocableHandlerMethod invocableMethod = this.createInvocableHandlerMethod(handlerMethod);
if (this.argumentResolvers != null) {
invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);
}

if (this.returnValueHandlers != null) {
invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);
}

invocableMethod.setDataBinderFactory(binderFactory);
invocableMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer);
// 封装 ModelAndViewContainer
ModelAndViewContainer mavContainer = new ModelAndViewContainer();
mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request));
modelFactory.initModel(webRequest, mavContainer, invocableMethod);
mavContainer.setIgnoreDefaultModelOnRedirect(this.ignoreDefaultModelOnRedirect);
AsyncWebRequest asyncWebRequest = WebAsyncUtils.createAsyncWebRequest(request, response);
asyncWebRequest.setTimeout(this.asyncRequestTimeout);
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
asyncManager.setTaskExecutor(this.taskExecutor);
asyncManager.setAsyncWebRequest(asyncWebRequest);
asyncManager.registerCallableInterceptors(this.callableInterceptors);
asyncManager.registerDeferredResultInterceptors(this.deferredResultInterceptors);
Object result;
if (asyncManager.hasConcurrentResult()) {
result = asyncManager.getConcurrentResult();
mavContainer = (ModelAndViewContainer)asyncManager.getConcurrentResultContext()[0];
asyncManager.clearConcurrentResult();
LogFormatUtils.traceDebug(this.logger, (traceOn) -> {
String formatted = LogFormatUtils.formatValue(result, !traceOn);
return "Resume with async result [" + formatted + "]";
});
invocableMethod = invocableMethod.wrapConcurrentResult(result);
}
// ServletInvocableHandlerMethod ## invokeAndHandle()
// 执行和返回值处理
invocableMethod.invokeAndHandle(webRequest, mavContainer, new Object[0]);
if (asyncManager.isConcurrentHandlingStarted()) {
result = null;
return (ModelAndView)result;
}
// 获取ModelAndView对象
var15 = this.getModelAndView(mavContainer, modelFactory, webRequest);
} finally {
webRequest.requestCompleted();
}

return var15;
}
}

GlobalControllerAdvice

ExceptionHandlerExceptionResolver
getModelFactory
1
2
3
ModelFactory
InvocableHandlerMethod

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
private ModelFactory getModelFactory(HandlerMethod handlerMethod, WebDataBinderFactory binderFactory) {
SessionAttributesHandler sessionAttrHandler = getSessionAttributesHandler(handlerMethod);
Class<?> handlerType = handlerMethod.getBeanType();
// 当前处理类型 对应的handler
Set<Method> methods = this.modelAttributeCache.get(handlerType);
if (methods == null) {
methods = MethodIntrospector.selectMethods(handlerType, MODEL_ATTRIBUTE_METHODS);
this.modelAttributeCache.put(handlerType, methods);
}
List<InvocableHandlerMethod> attrMethods = new ArrayList<>();
// Global methods first --- 先 添加全局
this.modelAttributeAdviceCache.forEach((controllerAdviceBean, methodSet) -> {
if (controllerAdviceBean.isApplicableToBeanType(handlerType)) {
Object bean = controllerAdviceBean.resolveBean();
for (Method method : methodSet) {
attrMethods.add(createModelAttributeMethod(binderFactory, bean, method));
}
}
});
// 后添加 对应的 handler method
for (Method method : methods) {
Object bean = handlerMethod.getBean();
attrMethods.add(createModelAttributeMethod(binderFactory, bean, method));
}
return new ModelFactory(attrMethods, binderFactory, sessionAttrHandler);
}

HandlerMethod

方法执行,封装

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 class HandlerMethod {
protected static final Log logger = LogFactory.getLog(HandlerMethod.class);
private final Object bean;
@Nullable
private final BeanFactory beanFactory;
@Nullable
private final MessageSource messageSource;
private final Class<?> beanType;
private final Method method;
private final Method bridgedMethod;
private final MethodParameter[] parameters;
@Nullable
private HttpStatus responseStatus;
@Nullable
private String responseStatusReason;
@Nullable
private HandlerMethod resolvedFromHandlerMethod;
@Nullable
private volatile List<Annotation[][]> interfaceParameterAnnotations;
private final String description;

//ReturnValueMethodParameter -> HandlerMethodParameter -> SynthesizingMethodParameter -> MethodParameter
// 获取保存返回值类型
private class ReturnValueMethodParameter extends HandlerMethod.HandlerMethodParameter {
@Nullable
private final Class<?> returnValueType;
} // 获取保存方法的注解
protected class HandlerMethodParameter extends SynthesizingMethodParameter {
@Nullable
private volatile Annotation[] combinedAnnotations;
}
}

image-20230423151139139

image-20230423151125205

ServletInvocableHandlerMethod

是对InvocableHandlerMethod的增强,能够处理返回值,将返回值写入Response,而不是返回ModelAndView

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
public class ServletInvocableHandlerMethod extends InvocableHandlerMethod {
private static final Method CALLABLE_METHOD = ClassUtils.getMethod(Callable.class, "call", new Class[0]);
@Nullable
private HandlerMethodReturnValueHandlerComposite returnValueHandlers;
/// 调用和处理 -----调用方法,处理返回值--requestMapping
public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception {
// 方法的执行与调用
Object returnValue = this.invokeForRequest(webRequest, mavContainer, providedArgs);
this.setResponseStatus(webRequest);
if (returnValue == null) {
if (this.isRequestNotModified(webRequest) || this.getResponseStatus() != null || mavContainer.isRequestHandled()) {
this.disableContentCachingIfNecessary(webRequest);
mavContainer.setRequestHandled(true);
return;
}
} else if (StringUtils.hasText(this.getResponseStatusReason())) {
mavContainer.setRequestHandled(true);
return;
}

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

try { // 返回值处理 -- returnValueHandlers去处理返回值,(主要为写入response)
this.returnValueHandlers.handleReturnValue(returnValue, this.getReturnValueType(returnValue), mavContainer, webRequest);
} catch (Exception var6) {
if (logger.isTraceEnabled()) {
logger.trace(this.formatErrorForReturnValue(returnValue), var6);
}

throw var6;
}
}
}

InvocableHandlerMethod

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class InvocableHandlerMethod extends HandlerMethod {
private static final Object[] EMPTY_ARGS = new Object[0];
private HandlerMethodArgumentResolverComposite resolvers = new HandlerMethodArgumentResolverComposite();
private ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
@Nullable
private WebDataBinderFactory dataBinderFactory;

// ServletInvocableHandlerMethod ## invokeAndHandler() -->
// InvocableHandlerMethod ## invokeForRequest()
public Object invokeForRequest(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception {
Object[] args = this.getMethodArgumentValues(request, mavContainer, providedArgs);
return this.doInvoke(args);
}
// 方法执行
protected Object doInvoke(Object... args) throws Exception {
Method method = this.getBridgedMethod();

try {
return KotlinDetector.isSuspendingFunction(method) ? CoroutinesUtils.invokeSuspendingFunction(method, this.getBean(), args) : method.invoke(this.getBean(), args);
}
}
}

image-20230423151309721

MethodParameter

封装 方法参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// package org.springframework.core;
public class MethodParameter {
private static final Annotation[] EMPTY_ANNOTATION_ARRAY = new Annotation[0];
private final Executable executable;
private final int parameterIndex;
@Nullable
private volatile Parameter parameter;
private int nestingLevel;
@Nullable
Map<Integer, Integer> typeIndexesPerLevel;
@Nullable
private volatile Class<?> containingClass;
@Nullable
private volatile Class<?> parameterType;
@Nullable
private volatile Type genericParameterType;
@Nullable
private volatile Annotation[] parameterAnnotations;
@Nullable
private volatile ParameterNameDiscoverer parameterNameDiscoverer;
@Nullable
private volatile String parameterName;
@Nullable
private volatile MethodParameter nestedMethodParameter;

image-20230423161105955

HandlerMethodReturnValueHandler

用于处理方法返回值的 Hanlder

1
2
3
4
5
6
public interface HandlerMethodReturnValueHandler {
// 通过返回值类型判断能够处理
boolean supportsReturnType(MethodParameter returnType);
// 具体的处理请求
void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception;
}

HandlerMethodReturnValueHandlerComposite

相当于抽象类的实现,用于转发 当前的方法到具体实现

1
2
3
4
public class HandlerMethodReturnValueHandlerComposite implements HandlerMethodReturnValueHandler {
private final List<HandlerMethodReturnValueHandler> returnValueHandlers = new ArrayList();

}

ResponseBodyEmitterReturnValueHandler

将返回值写入 返回体中

1
2
3
4
public class ResponseBodyEmitterReturnValueHandler implements HandlerMethodReturnValueHandler {
private final List<HttpMessageConverter<?>> sseMessageConverters;
private final ReactiveTypeHandler reactiveHandler;
}

image-20230424103522714

HandlerExceptionResolver

异常处理解析

1
2
3
4
public interface HandlerExceptionResolver {
@Nullable
ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex);
}

ExceptionHandlerExceptionResolver

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
public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExceptionResolver implements ApplicationContextAware, InitializingBean {
private static final boolean shouldIgnoreXml = SpringProperties.getFlag("spring.xml.ignore");
@Nullable
private List<HandlerMethodArgumentResolver> customArgumentResolvers;
@Nullable
private HandlerMethodArgumentResolverComposite argumentResolvers;
@Nullable
private List<HandlerMethodReturnValueHandler> customReturnValueHandlers;
@Nullable
private HandlerMethodReturnValueHandlerComposite returnValueHandlers;
private List<HttpMessageConverter<?>> messageConverters = new ArrayList();
private ContentNegotiationManager contentNegotiationManager = new ContentNegotiationManager();
private final List<Object> responseBodyAdvice = new ArrayList();
@Nullable
private ApplicationContext applicationContext;
private final Map<Class<?>, ExceptionHandlerMethodResolver> exceptionHandlerCache = new ConcurrentHashMap(64);
private final Map<ControllerAdviceBean, ExceptionHandlerMethodResolver> exceptionHandlerAdviceCache = new LinkedHashMap();
// 方法初始化的时候执行一次 ---作用暂时未知 --
static {
try {
NO_MATCHING_EXCEPTION_HANDLER_METHOD = ExceptionHandlerMethodResolver.class.getDeclaredMethod("noMatchingExceptionHandler");
} catch (NoSuchMethodException var1) {
throw new IllegalStateException("Expected method not found: " + var1);
}
}
private void noMatchingExceptionHandler() {
}

// InitializingBean的 afterPropertiesSet()
public void afterPropertiesSet() {
// 初始化异常处理的Advice 缓存
this.initExceptionHandlerAdviceCache();
List handlers;
// 参数解析器初始化,并添加处理链
if (this.argumentResolvers == null) {
handlers = this.getDefaultArgumentResolvers();
this.argumentResolvers = (new HandlerMethodArgumentResolverComposite()).addResolvers(handlers);
}
// 返回值解析器初始化,并添加处理链
if (this.returnValueHandlers == null) {
handlers = this.getDefaultReturnValueHandlers();
this.returnValueHandlers = (new HandlerMethodReturnValueHandlerComposite()).addHandlers(handlers);
}

}
// 初始化 ControllerAdvice中的@ExceptionHandler方法的缓存
private void initExceptionHandlerAdviceCache() {
if (this.getApplicationContext() != null) {
// 获取ControllerAdviceBean
List<ControllerAdviceBean> adviceBeans = ControllerAdviceBean.findAnnotatedBeans(this.getApplicationContext());
Iterator var2 = adviceBeans.iterator();
// 遍历 ControllerAdviceBean,寻找包含 @ExceptionHandler的Bean的ControllerAdviceBean
while(var2.hasNext()) {
// 包含了注解下的Bean的所有信息
ControllerAdviceBean adviceBean = (ControllerAdviceBean)var2.next();
// 获取beanType
Class<?> beanType = adviceBean.getBeanType();
// 初始化ExceptionHandlerMethodResolver,
// 同时解析当前Bean的方法中含有@ExceptionHandler注解的方法,加入集合
ExceptionHandlerMethodResolver resolver = new ExceptionHandlerMethodResolver(beanType);
if (resolver.hasExceptionMappings()) {
this.exceptionHandlerAdviceCache.put(adviceBean, resolver);
}

if (ResponseBodyAdvice.class.isAssignableFrom(beanType)) {
this.responseBodyAdvice.add(adviceBean);
}
}

if (this.logger.isDebugEnabled()) {
int handlerSize = this.exceptionHandlerAdviceCache.size();
int adviceSize = this.responseBodyAdvice.size();
}

}
}

}

ExceptionHandlerMethodResolver

@ExceptionHandler的异常处理方法的解析 和 缓存

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
public class ExceptionHandlerMethodResolver {
// 解析当前方法的 @ExceptionHandler 注解
public static final MethodFilter EXCEPTION_HANDLER_METHODS = (method) -> {
return AnnotatedElementUtils.hasAnnotation(method, ExceptionHandler.class);
};
private static final Method NO_MATCHING_EXCEPTION_HANDLER_METHOD;
// 包含 @ExceptionHandler 注解的方法集合
private final Map<Class<? extends Throwable>, Method> mappedMethods = new HashMap(16);
// 缓存
private final Map<Class<? extends Throwable>, Method> exceptionLookupCache = new ConcurrentReferenceHashMap(16);

/// ExceptionHandlerExceptionResolver ## new ExceptionHandlerMethodResolver(beanType);
// 同时解析当前Bean的方法中含有@ExceptionHandler注解的方法,加入集合
public ExceptionHandlerMethodResolver(Class<?> handlerType) {
//
Iterator var2 = MethodIntrospector.selectMethods(handlerType, EXCEPTION_HANDLER_METHODS).iterator();
while(var2.hasNext()) {
Method method = (Method)var2.next();
// 推断方法
Iterator var4 = this.detectExceptionMappings(method).iterator();
// 玄幻添加
while(var4.hasNext()) {
Class<? extends Throwable> exceptionType = (Class)var4.next();
this.addExceptionMapping(exceptionType, method);
}
}
}
}
// 方法内省
public final class MethodIntrospector {
public static Set<Method> selectMethods(Class<?> targetType, MethodFilter methodFilter) {
return selectMethods(targetType, (method) -> {
return methodFilter.matches(method) ? Boolean.TRUE : null;
}).keySet();
}
}

@Exception 注册

ExceptionHandlerExceptionResolver

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
public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExceptionResolver
implements ApplicationContextAware, InitializingBean {
@Override // spring bean 初始化的时候执行
public void afterPropertiesSet() {
// Do this first, it may add ResponseBodyAdvice beans
// 初始化 ExceptionHandler Advice cache === @ExceptionHandler method
initExceptionHandlerAdviceCache();

if (this.argumentResolvers == null) {
List<HandlerMethodArgumentResolver> resolvers = getDefaultArgumentResolvers();
this.argumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);
}
if (this.returnValueHandlers == null) {
List<HandlerMethodReturnValueHandler> handlers = getDefaultReturnValueHandlers();
this.returnValueHandlers = new HandlerMethodReturnValueHandlerComposite().addHandlers(handlers);
}
}

// 初始化
private void initExceptionHandlerAdviceCache() {
if (getApplicationContext() == null) {
return;
}

List<ControllerAdviceBean> adviceBeans = ControllerAdviceBean.findAnnotatedBeans(getApplicationContext());
for (ControllerAdviceBean adviceBean : adviceBeans) {
Class<?> beanType = adviceBean.getBeanType();
if (beanType == null) {
throw new IllegalStateException("Unresolvable type for ControllerAdviceBean: " + adviceBean);
} // 根据 controller advice(@ControllerAdvice 注解)内的 @ExceptionHandler 注解的方法 (BeanType) 解析为
// ExceptionHandlerMethodResolver (根据 异常类,划分 handler method)
ExceptionHandlerMethodResolver resolver = new ExceptionHandlerMethodResolver(beanType);
if (resolver.hasExceptionMappings()) {
this.exceptionHandlerAdviceCache.put(adviceBean, resolver);
}
if (ResponseBodyAdvice.class.isAssignableFrom(beanType)) {
this.responseBodyAdvice.add(adviceBean);
}
}

if (logger.isDebugEnabled()) {
int handlerSize = this.exceptionHandlerAdviceCache.size();
int adviceSize = this.responseBodyAdvice.size();
if (handlerSize == 0 && adviceSize == 0) {
logger.debug("ControllerAdvice beans: none");
}
else {
logger.debug("ControllerAdvice beans: " +
handlerSize + " @ExceptionHandler, " + adviceSize + " ResponseBodyAdvice");
}
}
}

}

ExceptionHandlerMethodResolver

解析 异常@ExceptionHandler 注解的方法。=== 该注解必须配合@ControllerAdvice 使用

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
public class ExceptionHandlerMethodResolver {

/**
* A filter for selecting {@code @ExceptionHandler} methods.
*/
// 解析出当前方法的中 包含 注解@ExceptionHandler 的 method
public static final MethodFilter EXCEPTION_HANDLER_METHODS = method ->
AnnotatedElementUtils.hasAnnotation(method, ExceptionHandler.class);

private static final Method NO_MATCHING_EXCEPTION_HANDLER_METHOD;
// ExceptionHandlerExceptionResolver ## initExceptionHandlerAdviceCache()
// 根据方法类型 初始化
public ExceptionHandlerMethodResolver(Class<?> handlerType) {
// 根据 内部类的功能获取对应method
for (Method method : MethodIntrospector.selectMethods(handlerType, EXCEPTION_HANDLER_METHODS)) {
// 根据方法接解析 注解上的 异常class
for (Class<? extends Throwable> exceptionType : detectExceptionMappings(method)) {
// 添加 exception tpye 和 method 的映射
addExceptionMapping(exceptionType, method);
}
}
}


/**
* Extract exception mappings from the {@code @ExceptionHandler} annotation first,
* and then as a fallback from the method signature itself.
*/
@SuppressWarnings("unchecked")
private List<Class<? extends Throwable>> detectExceptionMappings(Method method) {
List<Class<? extends Throwable>> result = new ArrayList<>();
// 异常解析
detectAnnotationExceptionMappings(method, result);
if (result.isEmpty()) {
for (Class<?> paramType : method.getParameterTypes()) {
if (Throwable.class.isAssignableFrom(paramType)) {
result.add((Class<? extends Throwable>) paramType);
}
}
}
if (result.isEmpty()) {
throw new IllegalStateException("No exception types mapped to " + method);
}
return result;
}

// 解析
private void detectAnnotationExceptionMappings(Method method, List<Class<? extends Throwable>> result) {
ExceptionHandler ann = AnnotatedElementUtils.findMergedAnnotation(method, ExceptionHandler.class);
Assert.state(ann != null, "No ExceptionHandler annotation");
result.addAll(Arrays.asList(ann.value()));
}
// 添加 m
private void addExceptionMapping(Class<? extends Throwable> exceptionType, Method method) {
Method oldMethod = this.mappedMethods.put(exceptionType, method);
if (oldMethod != null && !oldMethod.equals(method)) {
throw new IllegalStateException("Ambiguous @ExceptionHandler method mapped for [" +
exceptionType + "]: {" + oldMethod + ", " + method + "}");
}
}



}

Advice

ControllerAdviceBean

@ControllerAdvice注解所在Bean的信息封装

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
public class ControllerAdviceBean implements Ordered {
private final Object beanOrName;
private final boolean isSingleton;
//
private Object resolvedBean;
// 注解所在bean的类型
private final Class<?> beanType;
// @ControllerAdvice注解属性值的信息封装
private final HandlerTypePredicate beanTypePredicate;
@Nullable
private final BeanFactory beanFactory;
@Nullable
private Integer order;
public static List<ControllerAdviceBean> findAnnotatedBeans(ApplicationContext context) {
ListableBeanFactory beanFactory = context;
if (context instanceof ConfigurableApplicationContext) {
beanFactory = ((ConfigurableApplicationContext)context).getBeanFactory();
}

List<ControllerAdviceBean> adviceBeans = new ArrayList();
String[] var3 = BeanFactoryUtils.beanNamesForTypeIncludingAncestors((ListableBeanFactory)beanFactory, Object.class);
int var4 = var3.length;

for(int var5 = 0; var5 < var4; ++var5) {
String name = var3[var5];
if (!ScopedProxyUtils.isScopedTarget(name)) {
ControllerAdvice controllerAdvice = (ControllerAdvice)
// 通过BeanName和注解.class,寻找Bean对应的
// @ControllerAdvice的注解信息
((ListableBeanFactory)beanFactory).findAnnotationOnBean(name, ControllerAdvice.class);
if (controllerAdvice != null) {
adviceBeans.add(new ControllerAdviceBean(name, (BeanFactory)beanFactory, controllerAdvice));
}
}
}

OrderComparator.sort(adviceBeans);
return adviceBeans;
}

public ControllerAdviceBean(String beanName, BeanFactory beanFactory, @Nullable ControllerAdvice controllerAdvice) {
this.beanOrName = beanName;
this.isSingleton = beanFactory.isSingleton(beanName);
this.beanType = getBeanType(beanName, beanFactory);
// 创建 HandlerTypePredicate对象,封装注解的额外信息
// 通过BeanType 或者ControllerAdvice进行创建
this.beanTypePredicate = controllerAdvice != null ? createBeanTypePredicate(controllerAdvice) : createBeanTypePredicate(this.beanType);
this.beanFactory = beanFactory;
}

private static HandlerTypePredicate createBeanTypePredicate(@Nullable ControllerAdvice controllerAdvice) {
return controllerAdvice != null ? HandlerTypePredicate.builder().basePackage(controllerAdvice.basePackages()).basePackageClass(controllerAdvice.basePackageClasses()).assignableType(controllerAdvice.assignableTypes()).annotation(controllerAdvice.annotations()).build() : HandlerTypePredicate.forAnyHandlerType();
}
}

HandlerTypePredicate

取出注解的属性信息,封装为类方便调用

1
2
3
4
5
6
7
8
public final class HandlerTypePredicate implements Predicate<Class<?>> {
// 注解属性包含的包路径
private final Set<String> basePackages;
// 注解设置的可转让类型
private final List<Class<?>> assignableTypes;
// 注解属性包含的注解信息
private final List<Class<? extends Annotation>> annotations;
}

ControllerAdvice

来自@ControllerAdvice的全局@ExceptionHandler方法在@Controller的本地方法之后应用。相比之下,全局的@ModelAttribute和@InitBinder方法在局部方法之前应用。

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
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface ControllerAdvice {
@AliasFor("basePackages")
String[] value() default {};

@AliasFor("value")
String[] basePackages() default {};

Class<?>[] basePackageClasses() default {};

Class<?>[] assignableTypes() default {};

Class<? extends Annotation>[] annotations() default {};
}
// Target all Controllers annotated with @RestController
@ControllerAdvice(annotations = RestController.class)
public class ExampleAdvice1 {}

// Target all Controllers within specific packages
@ControllerAdvice("org.example.controllers")
public class ExampleAdvice2 {}

// Target all Controllers assignable to specific classes
@ControllerAdvice(assignableTypes = {ControllerInterface.class, AbstractController.class})
public class ExampleAdvice3 {}
@InitBinder @ModelAttribute

RequestBodyAdvice

@ExceptionHandler

ExceptionHandlerMethodResolver

RequestBodyAdvice

1
2
3
4
5
6
7
8
9
10
public interface RequestBodyAdvice {
boolean supports(MethodParameter methodParameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType);

HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) throws IOException;

Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType);

@Nullable
Object handleEmptyBody(@Nullable Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType);
}

ResponseBodyAdvice

1
2
3
4
5
6
public interface ResponseBodyAdvice<T> {
boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType);

@Nullable
T beforeBodyWrite(@Nullable T body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response);
}

image-20230424111034831

其他参数

ModelAndView

1
2
3
4
5
6
7
8
9
public class ModelAndView {
@Nullable
private Object view;
@Nullable
private ModelMap model;
@Nullable
private HttpStatus status;
private boolean cleared = false;
}

image-20230423160939306

Model

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public interface Model {
Model addAttribute(String var1, @Nullable Object var2);

Model addAttribute(Object var1);

Model addAllAttributes(Collection<?> var1);

Model addAllAttributes(Map<String, ?> var1);

Model mergeAttributes(Map<String, ?> var1);

boolean containsAttribute(String var1);

@Nullable
Object getAttribute(String var1);

Map<String, Object> asMap();
}

RedirectAttributes

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public interface RedirectAttributes extends Model {
RedirectAttributes addAttribute(String attributeName, @Nullable Object attributeValue);

RedirectAttributes addAttribute(Object attributeValue);

RedirectAttributes addAllAttributes(Collection<?> attributeValues);

RedirectAttributes mergeAttributes(Map<String, ?> attributes);

RedirectAttributes addFlashAttribute(String attributeName, @Nullable Object attributeValue);

RedirectAttributes addFlashAttribute(Object attributeValue);
// 用于重定向的参数传递 -- FlashAttributes
Map<String, ?> getFlashAttributes();
}

HtttpMessage

1
2
3
public interface HttpMessage {
HttpHeaders getHeaders();
}

HttpInputMessage

1
2
3
public interface HttpInputMessage extends HttpMessage {
InputStream getBody() throws IOException;
}

HttpRequest

1
2
3
4
5
6
7
8
9
10
public interface HttpRequest extends HttpMessage {
@Nullable
default HttpMethod getMethod() {
return HttpMethod.resolve(this.getMethodValue());
}

String getMethodValue();

URI getURI();
}

ServerHttpRequest

1
2
3
4
5
6
7
8
9
10
public interface ServerHttpRequest extends HttpRequest, HttpInputMessage {
@Nullable
Principal getPrincipal();

InetSocketAddress getLocalAddress();

InetSocketAddress getRemoteAddress();

ServerHttpAsyncRequestControl getAsyncRequestControl(ServerHttpResponse response);
}

ServletServerHttpRequest — 具体实现

image-20230423143831812

HttpOutputMessage

1
2
3
public interface HttpOutputMessage extends HttpMessage {
OutputStream getBody() throws IOException;
}

ServerHttpResponse

1
2
3
4
5
6
7
public interface ServerHttpResponse extends HttpOutputMessage, Flushable, Closeable {
void setStatusCode(HttpStatus status);

void flush() throws IOException;

void close();
}

ServletServerHttpResponse – 具体实现

image-20230423143843214

HttpSession

Tomcat

Session — Tomcat

StandardSessionFacade — Tomcat

StandardSession – Tomcat

Spring Session

Session – Spring Session

HttpSessionAdapter – Spring Session (分布式session)

image-20230423113512738

Spring WebFlux

Web on Reactive Stack (spring.io)

WebFlux

Spring Boot整合

Spring Web MVC

1
2
3
SpringApplication ##
context = this.createApplicationContext();

SpringApplication ## run () ## createApplicationContext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 创建  AnnotationConfigServletWebServerApplicationContext 
// 重写 onRefresh() 方法,实现自定义初始化类逻辑
protected ConfigurableApplicationContext createApplicationContext() {
Class<?> contextClass = this.applicationContextClass;
if (contextClass == null) {
try {
switch(this.webApplicationType) {
case SERVLET:
contextClass = Class.forName("org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext");
break;
case REACTIVE:
contextClass = Class.forName("org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext");
break;
default:
contextClass = Class.forName("org.springframework.context.annotation.AnnotationConfigApplicationContext");
}
} catch (ClassNotFoundException var3) {
throw new IllegalStateException("Unable create a default ApplicationContext, please specify an ApplicationContextClass", var3);
}
}

return (ConfigurableApplicationContext)BeanUtils.instantiateClass(contextClass);
}

AnnotationConfigServletWebServerApplicationContext

父类 : ServletWebServerApplicationContext -> GenericWebApplicationContext ## onRefresh()

image-20230504120126998

run() ## refresh()

ServletWebServerApplicationContext ## onRefresh()

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
public class ServletWebServerApplicationContext extends GenericWebApplicationContext implements ConfigurableWebServerApplicationContext {
private static final Log logger = LogFactory.getLog(ServletWebServerApplicationContext.class);
public static final String DISPATCHER_SERVLET_NAME = "dispatcherServlet";
private volatile WebServer webServer;
private ServletConfig servletConfig;
private String serverNamespace;
// 重写onRefresh,实现自定义逻辑
protected void onRefresh() {
super.onRefresh();
this.createWebServer();
}

// 创建webServer 服务
private void createWebServer() {
WebServer webServer = this.webServer;
ServletContext servletContext = this.getServletContext();
// 如果都为空,就准备关闭服务
if (webServer == null && servletContext == null) {
ServletWebServerFactory factory = this.getWebServerFactory();
this.webServer = factory.getWebServer(new ServletContextInitializer[]{this.getSelfInitializer()});
this.getBeanFactory().registerSingleton("webServerGracefulShutdown", new WebServerGracefulShutdownLifecycle(this.webServer));
this.getBeanFactory().registerSingleton("webServerStartStop", new WebServerStartStopLifecycle(this, this.webServer));
// 不为空,初始化信息
} else if (servletContext != null) {
try { //web.servlet 的-- ServletContextInitializer
// 初始化方法调用
this.getSelfInitializer().onStartup(servletContext);
} catch (ServletException var4) {
throw new ApplicationContextException("Cannot initialize servlet context", var4);
}
}
// 初始化PropertySource -- 资源,配置文件初始化
this.initPropertySources();
}
}

ServletContextInitializer

1
2
3
4
@FunctionalInterface
public interface ServletContextInitializer {
void onStartup(ServletContext servletContext) throws ServletException;
}

image-20230504120640787

GenericWebApplicationContext ## initPropertySources

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class GenericWebApplicationContext extends GenericApplicationContext implements ConfigurableWebApplicationContext, ThemeSource {
@Nullable
private ServletContext servletContext;
@Nullable
private ThemeSource themeSource;
// 具体初始方式
protected void initPropertySources() {
ConfigurableEnvironment env = this.getEnvironment();
if (env instanceof ConfigurableWebEnvironment) {
((ConfigurableWebEnvironment)env).initPropertySources(this.servletContext, (ServletConfig)null);
}
}

}

ConfigurableWebEnvironment

关键类:StandardServletEnvironment

对于PropertySource还不熟

1
2
3
public interface ConfigurableWebEnvironment extends ConfigurableEnvironment {
void initPropertySources(@Nullable ServletContext servletContext, @Nullable ServletConfig servletConfig);
}

image-20230504121149074

StandardServletEnvironment

1
2
3
4
5
6
7
8
9
10
public class StandardServletEnvironment extends StandardEnvironment implements ConfigurableWebEnvironment {
public static final String SERVLET_CONTEXT_PROPERTY_SOURCE_NAME = "servletContextInitParams";
public static final String SERVLET_CONFIG_PROPERTY_SOURCE_NAME = "servletConfigInitParams";
public static final String JNDI_PROPERTY_SOURCE_NAME = "jndiProperties";
private static final boolean jndiPresent = ClassUtils.isPresent("javax.naming.InitialContext", StandardServletEnvironment.class.getClassLoader());
// 具体实现
public void initPropertySources(@Nullable ServletContext servletContext, @Nullable ServletConfig servletConfig) {
WebApplicationContextUtils.initServletPropertySources(this.getPropertySources(), servletContext, servletConfig);
}
}

Spring Web模块
http://example.com/2023/06/01/Spring家族/Spring Web/
作者
where
发布于
2023年6月1日
许可协议