抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

摘要:本文分析了SpringMVC的工作流程,包括请求处理的各个阶段和核心对象的协作机制。

环境

Windows 10 企业版 LTSC 21H2
Java 1.8
Tomcat 8.5.50
Maven 3.6.3
Spring 5.2.25.RELEASE

1 基本流程

SpringMVC的工作流程是围绕DispatcherServlet前端控制器展开的,由它统一处理所有请求。

核心流程:
20260112103332-核心流程

说明:

  1. 发送请求。服务器接受用户请求,DispatcherServlet捕获请求。
  2. 获取处理器执行链。根据配置匹配路径,通过HandlerMapping处理器映射器获取Handler处理器和InterceptorList拦截器列表,封装为HandlerExecutionChain处理器执行链。
  3. 返回处理器执行链。返回HandlerExecutionChain处理器执行链。
  4. 获取处理器适配器。根据HandlerExecutionChain处理器执行链中的Handler处理器,匹配HandlerAdapter处理器适配器。
  5. 返回处理器适配器。返回HandlerAdapter处理器适配器。
  6. 执行业务方法。使用HandlerAdapter处理器适配器执行Handler处理器对应的业务方法,根据配置将结果封装为ModelAndView模型视图。
  7. 返回业务结果。返回ModelAndView模型视图。
  8. 处理视图。判断是否需要解析视图:如果不用解析视图,则直接返回视图;如果需要解析视图,则匹配ViewResolver视图解析器解析视图。
  9. 返回视图。使用View视图填充Model模型数据,处理响应。
  10. 响应请求。将响应返回给用户。

详细流程:
20260112103517-详细流程

2 源码分析

2.1 请求接收

根据web.xml配置文件中的配置,使用DispatcherServlet匹配/请求,所有请求都会经过DispatcherServlet处理。

2.2 准备处理请求

DispatcherServlet继承自FrameworkServlet,FrameworkServlet间接继承自HttpServlet,请求会调用service()方法。

DipatcherServlet没有实现service()方法,所以调用FrameworkServlet的service()方法:

java
1
2
3
4
5
6
7
8
9
10
11
12
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取请求类型
HttpMethod httpMethod = HttpMethod.resolve(request.getMethod());
// 根据请求类型判断是否为PATCH请求或未知请求
if (httpMethod == HttpMethod.PATCH || httpMethod == null) {
// 准备处理请求
processRequest(request, response);
} else {
// 调用相关方法处理请求
super.service(request, response);
}
}

调用HttpServlet的service()方法,根据请求类型调用方法:

java
1
2
3
4
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 根据请求类型调用方法
doXxx(req, resp);
}

调用FrameworkServlet的doXxx()方法,准备处理请求:

java
1
2
3
4
protected final void doXxx(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 准备处理请求
processRequest(request, response);
}

2.3 开始处理请求

调用FrameworkServlet的processRequest()方法,开始处理请求:

java
1
2
3
4
5
6
7
8
9
10
protected final void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置LocaleContext
LocaleContext previousLocaleContext = LocaleContextHolder.getLocaleContext();
LocaleContext localeContext = buildLocaleContext(request);
// 设置RequestAttributes
RequestAttributes previousAttributes = RequestContextHolder.getRequestAttributes();
ServletRequestAttributes requestAttributes = buildRequestAttributes(request, response, previousAttributes);
// 开始处理请求
doService(request, response);
}

调用DispatcherServlet的doService()方法,执行处理请求前的设置:

java
1
2
3
4
5
6
7
8
9
10
11
12
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 设置请求属性
request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, getWebApplicationContext());
request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver);
request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver);
request.setAttribute(THEME_SOURCE_ATTRIBUTE, getThemeSource());
// 设置FlashMap
request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());
request.setAttribute(FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager);
// 继续处理请求
doDispatch(request, response);
}

调用DispatcherServlet的doDispatch()方法,继续处理请求:

java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 处理上传请求
HttpServletRequest processedRequest = checkMultipart(request);
// 获取处理器执行链
HandlerExecutionChain mappedHandler = getHandler(processedRequest);
// 获取处理器适配器
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// 使用处理器执行链中的拦截器链进行前置检查
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
// 处理请求业务逻辑
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
// 处理视图名称,拼接前缀后缀
applyDefaultViewName(processedRequest, mv);
// 使用处理器执行链中的拦截器链进行后置检查
mappedHandler.applyPostHandle(processedRequest, response, mv);
// 处理视图
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}

2.4 获取处理器执行链

2.4.1 匹配处理器映射器

调用DispatcherServlet的getHandler()方法,获取处理器执行链:

java
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;
}

调用AbstractHandlerMapping的getHandler()方法,获取处理器执行链:

java
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
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
// 获取处理器
Object handler = getHandlerInternal(request);
// 如果没有找到处理器,则使用默认处理器
if (handler == null) {
handler = getDefaultHandler();
}
// 如果没有默认处理器,则返回null
if (handler == null) {
return null;
}
// 如果处理器是字符串,则获取对应的处理器对象
if (handler instanceof String) {
String handlerName = (String) handler;
handler = obtainApplicationContext().getBean(handlerName);
}
// 封装普通处理器执行链
HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);
// 检查是否配置跨域或者预检请求
if (hasCorsConfigurationSource(handler) || CorsUtils.isPreFlightRequest(request)) {
// 封装跨域处理器执行链,确保在请求处理前进行检查
executionChain = getCorsHandlerExecutionChain(request, executionChain, config);
}
// 返回处理器执行链
return executionChain;
}

HandlerMapping用于根据请求获取处理器,有多种实现类,需要根据Controller的使用方式判断使用哪个实现类:

  • RequestMappingHandlerMapping:基于@RequestMapping注解配置映射,最常用的映射器。
  • BeanNameUrlHandlerMapping:基于Bean名称配置映射,默认自带映射。
  • SimpleUrlHandlerMapping:基于URL配置映射,需要显示配置映射,支持集中配置URL映射,支持通配符,支持批量配置。
  • 也支持通过实现HandlerMapping接口的方式自定义映射器。

2.4.2 获取处理器

调用AbstractHandlerMethodMapping的getHandlerInternal()方法,获取处理器:

java
1
2
3
4
5
6
7
8
protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
// 获取请求路径
String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
// 根据请求路径获取处理器
HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);
// 返回处理器
return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null);
}

调用AbstractHandlerMethodMapping的lookupHandlerMethod()方法,根据请求路径获取处理器:

java
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
protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {
// 准备匹配列表
List<Match> matches = new ArrayList<>();
// 根据请求路径直接匹配
List<T> directPathMatches = this.mappingRegistry.getMappingsByUrl(lookupPath);
// 如果可以直接匹配,检查直接匹配的映射,添加到匹配列表中
if (directPathMatches != null) {
addMatchingMappings(directPathMatches, matches, request);
}
// 如果不能直接匹配,检查所有注册的映射,添加到匹配列表中
if (matches.isEmpty()) {
addMatchingMappings(this.mappingRegistry.getMappings().keySet(), matches, request);
}
// 判断匹配列表是否为空
if (!matches.isEmpty()) {
// 如果匹配列表不为空,选择最佳匹配,最佳匹配如果重复抛出异常
Match bestMatch = matches.get(0);
if (matches.size() > 1) { ... }
// 设置最佳匹配的处理器
request.setAttribute(BEST_MATCHING_HANDLER_ATTRIBUTE, bestMatch.handlerMethod);
handleMatch(bestMatch.mapping, lookupPath, request);
return bestMatch.handlerMethod;
} else {
// 如果匹配列表是空的,处理无匹配情况
return handleNoMatch(this.mappingRegistry.getMappings().keySet(), lookupPath, request);
}
}

2.4.3 封装处理器执行链

2.4.3.1 封装普通处理器

调用AbstractHandlerMapping的getHandlerExecutionChain()方法,封装普通处理器执行链:

java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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;
}
2.4.3.2 封装跨域处理器

调用AbstractHandlerMapping的getCorsHandlerExecutionChain()方法,封装跨域处理器执行链:

java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
protected HandlerExecutionChain getCorsHandlerExecutionChain(HttpServletRequest request, HandlerExecutionChain chain, @Nullable CorsConfiguration config) {
// 检查当前请求是否为预检请求
if (CorsUtils.isPreFlightRequest(request)) {
// 获取普通处理器的拦截器列表
HandlerInterceptor[] interceptors = chain.getInterceptors();
// 封装预检处理器和拦截器列表,返回处理器执行链
return new HandlerExecutionChain(new PreFlightHandler(config), interceptors);
} else {
// 插入跨域拦截器
chain.addInterceptor(0, new CorsInterceptor(config));
// 返回处理器执行链
return chain;
}
}

2.5 获取处理器适配器

调用DispatcherServlet的getHandlerAdapter()方法,获取处理器适配器:

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

HandlerAdapter用于根据处理器执行业务逻辑,有多种实现类,需要根据Controller的使用方式判断使用哪个实现类:

  • RequestMappingHandlerAdapter:支持基于@RequestMapping注解的使用方式。最常用的适配器。
  • HttpRequestHandlerAdapter:支持实现HttpRequestHandler接口的使用方式。
  • SimpleControllerHandlerAdapter:支持实现Controller接口的使用方式,早期适配器。
  • SimpleServletHandlerAdapter:支持实现Servlet接口的使用方式,早期适配器。
  • 也支持通过实现HandlerAdapter接口的方式自定义处理。

2.6 处理请求业务逻辑

调用AbstractHandlerMethodAdapter的handle()方法,处理请求业务逻辑:

java
1
2
3
4
public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 处理请求业务逻辑
return handleInternal(request, response, (HandlerMethod) handler);
}

调用RequestMappingHandlerAdapter的handleInternal()方法,处理请求业务逻辑:

java
1
2
3
4
5
6
protected ModelAndView handleInternal(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
// 检查请求是否符合要求
checkRequest(request);
// 调用实际处理方法
return invokeHandlerMethod(request, response, handlerMethod);
}

调用RequestMappingHandlerAdapter的invokeHandlerMethod()方法,调用实际处理方法:

java
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
protected ModelAndView invokeHandlerMethod(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
// 封装请求和响应对象
ServletWebRequest webRequest = new ServletWebRequest(request, response);
// 创建数据绑定工厂,绑定请求参数
WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);
// 创建模型工厂,创建数据模型
ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);
// 封装处理器作为可执行的方法
ServletInvocableHandlerMethod invocableMethod = 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 mavContainer = new ModelAndViewContainer();
// 设置FlashMap
mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request));
// 初始化数据模型
modelFactory.initModel(webRequest, mavContainer, invocableMethod);
// 设置重定向忽略默认模型
mavContainer.setIgnoreDefaultModelOnRedirect(this.ignoreDefaultModelOnRedirect);
// 执行业务逻辑
invocableMethod.invokeAndHandle(webRequest, mavContainer);
// 处理模型视图
return getModelAndView(mavContainer, modelFactory, webRequest);
}

2.7 处理业务逻辑

2.7.1 执行业务逻辑

调用ServletInvocableHandlerMethod的invokeAndHandle()方法,执行业务逻辑:

java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception {
// 执行请求业务逻辑
Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);
// 设置响应状态码
setResponseStatus(webRequest);
// 处理没有返回值的情况
if ( ... ) {
// 标记不用处理返回值
mavContainer.setRequestHandled(true);
return;
}
// 标记需要处理返回值
mavContainer.setRequestHandled(false);
// 使用返回值处理器处理返回值
this.returnValueHandlers.handleReturnValue(returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
}

调用HandlerMethodReturnValueHandlerComposite的handleReturnValue()方法,使用返回值处理器处理返回值:

java
1
2
3
4
5
6
7
8
9
10
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( ... );
}
// 处理返回值
handler.handleReturnValue(returnValue, returnType, mavContainer, webRequest);
}

调用HandlerMethodReturnValueHandlerComposite的selectHandler()方法,获取返回值处理器:

java
1
2
3
4
5
6
7
8
9
private HandlerMethodReturnValueHandler selectHandler(@Nullable Object value, MethodParameter returnType) {
// 遍历所有返回值处理器,返回匹配的返回值处理器
for (HandlerMethodReturnValueHandler handler : this.returnValueHandlers) {
if (handler.supportsReturnType(returnType)) {
return handler;
}
}
return null;
}

HandlerMethodReturnValueHandler用于根据返回类型处理返回值,有多种实现类,需要根据返回类型判断使用哪个实现类:

  • RequestResponseBodyMethodProcessor:支持处理使用@ResponseBody注解的返回值,用于返回JSON数据。
  • HttpEntityMethodProcessor:支持处理返回类型为HttpEntity的返回值,用于返回响应实体。
  • ViewNameMethodReturnValueHandler:支持处理返回类型为String的返回值,用于返回视图页面。
  • ModelAndViewMethodReturnValueHandler:支持处理返回类型为ModelAndView的返回值,用于返回使用数据的视图页面。
  • 也支持通过实现HandlerMethodReturnValueHandler接口的方式自定义处理器。

2.7.2 处理返回值

2.7.2.1 处理视图

调用ViewNameMethodReturnValueHandler的handleReturnValue()方法,处理视图:

java
1
2
3
4
5
6
7
8
9
10
public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
// 获取视图名称
String viewName = returnValue.toString();
// 设置视图名称
mavContainer.setViewName(viewName);
// 如果视图名称为重定向视图格式,则标记重定向
if (isRedirectViewName(viewName)) {
mavContainer.setRedirectModelScenario(true);
}
}
2.7.2.2 处理JSON数据

调用RequestResponseBodyMethodProcessor的handleReturnValue()方法,处理JSON数据:

java
1
2
3
4
5
6
7
8
9
10
public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws IOException, HttpMediaTypeNotAcceptableException, HttpMessageNotWritableException {
// 标记不用处理返回值
mavContainer.setRequestHandled(true);
// 创建输入消息
ServletServerHttpRequest inputMessage = createInputMessage(webRequest);
// 创建输出消息
ServletServerHttpResponse outputMessage = createOutputMessage(webRequest);
// 写入返回值
writeWithMessageConverters(returnValue, returnType, inputMessage, outputMessage);
}

2.7.3 处理模型视图

调用RequestMappingHandlerAdapter的getModelAndView()方法,处理模型视图:

java
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 ModelAndView getModelAndView(ModelAndViewContainer mavContainer, ModelFactory modelFactory, NativeWebRequest webRequest) throws Exception {
// 使用模型工厂更新模型数据
modelFactory.updateModel(webRequest, mavContainer);
// 如果请求已经被处理,比如@ResponseBody注解,则返回null
if (mavContainer.isRequestHandled()) {
return null;
}
// 获取模型数据
ModelMap model = mavContainer.getModel();
// 创建模型视图
ModelAndView mav = new ModelAndView(mavContainer.getViewName(), model, mavContainer.getStatus());
// 处理视图
if (!mavContainer.isViewReference()) {
mav.setView((View) mavContainer.getView());
}
// 处理FlashMap
if (model instanceof RedirectAttributes) {
Map<String, ?> flashAttributes = ((RedirectAttributes) model).getFlashAttributes();
HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
if (request != null) {
RequestContextUtils.getOutputFlashMap(request).putAll(flashAttributes);
}
}
// 返回模型视图
return mav;
}

2.8 处理视图

2.8.1 准备视图

调用DispatcherServlet的processDispatchResult()方法,处理视图:

java
1
2
3
4
5
6
7
8
9
10
11
12
13
private void processDispatchResult(HttpServletRequest request, HttpServletResponse response, @Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv, @Nullable Exception exception) throws Exception {
// 处理异常
if (exception != null) { ... }
// 判断是否需要渲染视图
if (mv != null && !mv.wasCleared()) {
// 渲染视图
render(mv, request, response);
}
// 使用处理器执行链中的拦截器链进行结束处理
if (mappedHandler != null) {
mappedHandler.triggerAfterCompletion(request, response, null);
}
}

调用DispatcherServlet的render()方法,渲染视图:

java
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
protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {
// 本地化
Locale locale = (this.localeResolver != null ? this.localeResolver.resolveLocale(request) : request.getLocale());
response.setLocale(locale);
// 准备视图
View view;
// 获取视图名称
String viewName = mv.getViewName();
// 判断视图名称是否存在
if (viewName != null) {
// 通过名称获取视图
view = resolveViewName(viewName, mv.getModelInternal(), locale, request);
// 如果视图不存在,则抛出异常
if (view == null) {
throw new ServletException( ... );
}
} else {
// 通过对象获取视图
view = mv.getView();
// 如果视图不存在,则抛出异常
if (view == null) {
throw new ServletException( ... );
}
}
// 渲染视图
view.render(mv.getModelInternal(), request, response);
}

2.8.2 获取视图

2.8.2.1 通过名称获取视图

调用DispatcherServlet的resolveViewName()方法,通过名称获取视图:

java
1
2
3
4
5
6
7
8
9
10
11
12
protected View resolveViewName(String viewName, @Nullable Map<String, Object> model, Locale locale, HttpServletRequest request) throws Exception {
// 遍历所有视图解析器,返回视图对象
if (this.viewResolvers != null) {
for (ViewResolver viewResolver : this.viewResolvers) {
View view = viewResolver.resolveViewName(viewName, locale);
if (view != null) {
return view;
}
}
}
return null;
}

ViewResolver用于将视图名称解析为视图对象,有多种实现类,需要根据页面的格式判断使用哪个实现类:

  • InternalResourceViewResolver:支持解析JSP页面。最常见的解析器。
  • BeanNameViewResolver:支持将逻辑视图名解析为Bean对象。
  • XmlViewResolver:支持解析XML文件。
  • ResourceBundleViewResolver:支持解析属性文件。
  • 也支持通过实现ViewResolver接口的方式自定义处理。
2.8.2.2 通过对象获取视图

调用ModelAndView的getView()方法,通过对象获取视图:

java
1
2
3
4
public View getView() {
// 返回视图对象
return (this.view instanceof View ? (View) this.view : null);
}

2.8.3 渲染视图

调用AbstractView的render()方法,渲染视图:

java
1
2
3
4
5
6
7
8
public void render(@Nullable Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
// 合并模型数据
Map<String, Object> mergedModel = createMergedOutputModel(model, request, response);
// 准备响应
prepareResponse(request, response);
// 实际渲染逻辑
renderMergedOutputModel(mergedModel, getRequestToExpose(request), response);
}

评论