
一、框架预览

二、定义与对象
首先必须了解处理器即handler是什么:你在前期可以直接理解为controller方法
-
HttpServlet定义了规范, 但是如果不重写doGet方法的话就会报错
-
FrameworkServlet重写了doGet(),实现了HttpServletBean
-
DispatcherServlet:派发到处理器上
-
HanlderInterceptor,接口3个方法
-
preHandle//请求开始之前 postHandle//请求结束之后,画面渲染之前 afterCompletion//画面渲染之后。有的时候画面不存在,只有返回modelAndView时画面才存在,返回json时没有画面 //jdk8之后该接口有default,可以不重写
-
-
// 抽象类,都是空实现 // JDK8之前需要重写接口所有方法,如果直接使用这个抽象类省略重写方法 public abstract class HandlerInterceptorAdapter implements AsyncHandlerInterceptor { //内部是HandlerInterceptor接口 // 为了方便jdk8之前直接使用 @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return true; } -
HandlerMapping:处理请求到处理器,即映射到java方法的封装
- RequestMappingHandlerMapping:映射器+处理器
-
HandlerMethod:java方法的封装
-
HandlerAdapter:为了重写老式重写Controller接口的类。从HandlerMapping中拿到HandlerMethod后ha去参数解析等操作
-
MethodParameter:对HandlerMethod的参数的封装,比如还有
@PathVariable -
HandlerMethodArgumentResolver:对上面参数解析,比如请求
/getById/{1}就可以把id注入到id参数上。他的实现比如是解析@PathVariable,又比如是解析@RequestParam的-
// HandlerMethodArgumentResolver接口的方法 //返回true代表是@PathVariable,可以进入resolveArgument boolean supportsParameter(MethodParameter parameter); // Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer, NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception;
-
-
HandlerMethodArgumentResolverComposite:组合模式,持有全部的参数解析器resolver
-
组合模式就是说 list的调用方法和一个元素怒的调用方法是一样的
-
class HandlerMethodArgumentResolverComposite implements HandlerMethodArgumentResolver { private final List<HandlerMethodArgumentResolver> argumentResolvers = new LinkedList<>(); private final Map<MethodParameter, HandlerMethodArgumentResolver> argumentResolverCache = new ConcurrentHashMap<>(256); public HandlerMethodArgumentResolverComposite addResolver(HandlerMethodArgumentResolver resolver) { this.argumentResolvers.add(resolver); return this; } // 重点 // 是否支持解析该参数 public boolean supportsParameter(MethodParameter parameter) { return getArgumentResolver(parameter) != null; // 不为空 } // 重点 // 解析参数 public Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer, NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) { HandlerMethodArgumentResolver resolver = getArgumentResolver(parameter); if (resolver == null) { 报错无法解析参数类型 parameter.getParameterType() } return resolver.resolveArgument(parameter, mavContainer, webRequest, binderFactory); } private HandlerMethodArgumentResolver getArgumentResolver(MethodParameter parameter) { // 缓存 HandlerMethodArgumentResolver result = this.argumentResolverCache.get(parameter); // 缓存为空,遍历list if (result == null) { for (HandlerMethodArgumentResolver resolver : this.argumentResolvers) { if (resolver.supportsParameter(parameter)) { result = resolver; // 添加到缓存 this.argumentResolverCache.put(parameter, result); break; } } } return result; }
-
-
RequestResponseBodyMethodProcessor:实现了HandlerMethodArgumentResolver。处理两种body请求
@RequestBody、@ResponseBody-
public boolean supportsParameter(MethodParameter parameter) { return parameter.hasParameterAnnotation(RequestBody.class);//@RequestBody } public boolean supportsReturnType(MethodParameter returnType) { //@ResponseBody方法上或者类上有没有注解 return (AnnotatedElementUtils.hasAnnotation(returnType.getContainingClass(), ResponseBody.class) || returnType.hasMethodAnnotation(ResponseBody.class)); } // java对象转json public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest){ mavContainer.setRequestHandled(true); ServletServerHttpRequest inputMessage = createInputMessage(webRequest); ServletServerHttpResponse outputMessage = createOutputMessage(webRequest); // Try even with null return value. ResponseBodyAdvice could get involved. writeWithMessageConverters(returnValue, returnType, inputMessage, outputMessage); }
-
private方法也能被请求到
HttpServlet
protected void doGet(HttpServletRequest req,
HttpServletResponse resp) {
String protocol = req.getProtocol();
String msg = lStrings.getString("http.method_get_not_supported");
if (protocol.endsWith("1.1")) {
resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);//405
} else {
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);//400
}
}
FramewordServlet
重写了doGet
public abstract class FrameworkServlet
extends HttpServletBean
implements ApplicationContextAware {
@Override
protected final void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
@Override
protected final void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
// get和post都会跳转到这里 // 这个方法是final,而doService需要被重写,这是模板方法模式
protected final void processRequest(HttpServletRequest request,
HttpServletResponse response) {
try {
doService(request, response);//要被子类DispatcherServlet重写
}
finally {
resetContextHolders(request, previousLocaleContext, previousAttributes);
if (requestAttributes != null) {
requestAttributes.requestCompleted();
}
logResult(request, response, failureCause, asyncManager);
publishRequestHandledEvent(request, response, startTime, failureCause);
}
首先,Tomcat每次启动时都会加载并解析/WEB-INF/web.xml文件,所以可以先从web.xml找突破口,主要代码如下:
<servlet >
<servlet-name >spring-mvc</servlet-name>
<!-- servlet类 -->
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<!-- 初始化参数 -->
<init-param >
<param-name >contextConfigLocation</param-name>
<param-value >classpath:/spring-mvc.xml</param-value>
</init-param>
<!-- 启动时加载 -->
<load-on-startup >1</load-on-startup>
</servlet>
<servlet-mapping >
<servlet-name >spring-mvc</servlet-name>
<url-pattern >/</url-pattern>
</servlet-mapping>
我们可以从web.xml文件获得三个信息,分别是:servlet类为DispatcherServlet,它在启动时加载,加载时初始化参数contextConfigLocation为classpath下spring-mvc.xml的文件地址,接下来我们将目光移到DispatcherServlet类。
DispatcherServlet
很明显,它是一个Servlet的子类,其实不用说也知道,因为web.xml早已有配置。既然是Servlet,我们就要专注于它的service、doGet、doPost等相关方法,在它的父类FrameServlet,我们找到了service方法。
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
logRequest(request);
// Keep a snapshot of the request attributes in case of an include,
// to be able to restore the original attributes after the include.
Map<String, Object> attributesSnapshot = null;
if (WebUtils.isIncludeRequest(request)) {
attributesSnapshot = new HashMap<>();
Enumeration<?> attrNames = request.getAttributeNames();
while (attrNames.hasMoreElements()) {
String attrName = (String) attrNames.nextElement();
if (this.cleanupAfterInclude || attrName.startsWith(DEFAULT_STRATEGIES_PREFIX)) {
attributesSnapshot.put(attrName, request.getAttribute(attrName));
}
}
}
// Make framework objects available to handlers and view objects.
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());
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);
}
try {
// ====DispatcherServlet.doDispatch
doDispatch(request, response);
}
finally {
if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
// Restore the original attribute snapshot, in case of an include.
if (attributesSnapshot != null) {
restoreAttributesAfterInclude(request, attributesSnapshot);
}
}
}
}
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) {
String method = request.getMethod();
if (method.equalsIgnoreCase(RequestMethod.PATCH.name())) {
processRequest(request, response);
}
else {
// 调用父类的service方法
super.service(request, response);
}
}
根据service方法,我们一步步找到一个方法链service –> processRequest –> doService –> doDispatch,我们最终将目光定位在doDispatch,因为从它的方法体就可以看出它是整个SpringMVC的核心方法。
三、流程预览


- FrameworkdServlet.doGet()–>
- FrameworkdServlet.processRequest()
- DispatcherServlet.doService(request, response);
- DispatcherServlet.doDispatch()
dis流程

①getHandler(processedRequest)
②getHandlerAdapter
③mappedHandler.applyPreHandle(
④mv = ha.handle
⑤mappedHandler.applyPostHandle
⑥processDispatchResult
四、DispatcherServlet.doDispatch
获取controller流程
- 扫描整个项目,spring已经做了,定义了一个集合
- 拿到所有加了 @Controller注解的类
- 遍历类里面所有的方法对象
- 判断方法是否加了@RequestMapping注解
- @RequestMapping注解的value作为map的key。put(value,method对象)
- 根据用户发送的请求 拿到请求中的URI,如test.do
- 使用请求的uri作为map的key,去map中get,看看是否有返回值
handlerMappings是比如RequestMapping的,welcome的
每个handlerMapping有一个mappingRegistry,里面有个registry-map,key为如{POST/user}、{PUT/user}等,value为对应的MappingRegistration
doDispatch

// DispatcherServlet
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 原生请求,coyote请求,跟tomcat有关
HttpServletRequest processedRequest = request;
// 这个链
HandlerExecutionChain mappedHandler = null;
// 是否是文件上传,默认不是
boolean multipartRequestParsed = false;
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
try {
ModelAndView mv = null;
Exception dispatchException = null;
try {
// 处理文件上传请求,检查文件
processedRequest = checkMultipart(request);
// 发生变化代表是文件上传请求
multipartRequestParsed = processedRequest != request;
// 哪个handler能处理当前请求
// 解析请求,获取HandlerExecutionChain对象。即获取controller。类#方法()
mappedHandler = getHandler(processedRequest);//processedRequest是对request的封装
if (mappedHandler == null || mappedHandler.getHandler() == null) {
noHandlerFound(processedRequest, response);
return;
}
// 知道了handler还不够,还要反射调用方法,还要设置参数,把这些操作封装到了HandlerAdapter。用ha.handler()
// 从HandlerExecutionChain对象获取HandlerAdapter对象,实际上是从HandlerMapping对象中获取
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// Process last-modified header, if supported by the handler.
String method = request.getMethod();
boolean isGet = "GET".equals(method);
if (isGet || "HEAD".equals(method)) {
long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
return;
}
}
// 在controller方法执行前,调用拦截器的preHandle()
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
// 返回false的话直接返回
return;
}
try {
// 真正执行HandlerAdapter对象的handler方法,返回ModelAndView
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
}
finally {
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
}
applyDefaultViewName(request, mv);
// 在controller方法执行后,执行【拦截器】的postHandle()
mappedHandler.applyPostHandle(processedRequest, response, mv);
}
catch (Exception ex) {
dispatchException = ex;
}
// 进行视图解析
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
} catch (Exception ex) {
triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
} catch (Error err) {
triggerAfterCompletionWithError(processedRequest, response, mappedHandler, err);
}
finally {
if (asyncManager.isConcurrentHandlingStarted()) {
// Instead of postHandle and afterCompletion
mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
return;
}
// Clean up any resources used by a multipart request.
if (multipartRequestParsed) {
cleanupMultipart(processedRequest);
}
}
}
说它是核心一点也不为过,从上述代码的中文注释可以看出,它包含了解析请求,执行相关拦截器,执行handle方法(到这里关于handle方法是什么,我们一脸懵逼。别急,接下来我们会讲述,总之它很重要就对了),执行视图解析方法。
五、ds.getHandler
①ds.getHandler:从handlerMapping过去methodHandler
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
if (this.handlerMappings != null) {
// 遍历映射器。一直找,找到一个符合我们请求的映射器。从映射器中拿到处理器,即要拿到java方法,
// handlerMappings的类型是list,分别是
/*
RequestMappingHandlerMapping,//处理注解@RequestMapping,映射到handler。mapping.mappingRegistry.registry.mappingLookup()就能看到map,kv对映射RequestMappingInfo到HandlerMethod
BeanNameUrlHandlerMapping,
SimpleUrlHandlerMapping,
WelcomePageHandlerMapping
*/
for (HandlerMapping mapping : this.handlerMappings) {
// 调用映射器的getHandler //RequestMappingHandlerMapping // @RequestMapping
HandlerExecutionChain handler = mapping.getHandler(request); // @RequestMapping注解的
if (handler != null) {
return handler;
}
}
}
return null;
}
他会依次调用现有的handlerMappings集合,看看谁能处理当前的请求,这就是调用他们的getHandler()方法,要是处理不了他们就返回null了
RequestMapping中有个属性mappingRegistry,类型如下AbstractHandlerMethodMapping
private final MappingRegistry mappingRegistry = new MappingRegistry();//AbstractHandlerMethodMapping
mappingRegistry中有个属性mappingLookUp,是个map。第一个的key是"{GET/user/info/{firstName}}"->"...getUser()"
public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMapping implements InitializingBean {
生成了handler之后,里面的属性就有HandlerMethod,interceptorList,
HandlerMethod的属性如
- bean(controller的类型),
- beanFactory,
- bridgeMethod(匹配到的getUser方法)
拿到的handler就是mappedHandler,他的类型是HandlerExecutionChain
AbstractHandlerMapping.getHandler
public abstract class AbstractHandlerMapping
extends WebApplicationObjectSupport
implements HandlerMapping, Ordered, BeanNameAware {
// 查找hm中调用的方法
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
//
Object handler = getHandlerInternal(request);
if (handler == null) {
handler = getDefaultHandler();
}
if (handler == null) {
return null;
}
// Bean name or resolved handler?
if (handler instanceof String) {
String handlerName = (String) handler;
handler = obtainApplicationContext().getBean(handlerName);
}
HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);
if (logger.isTraceEnabled()) {
logger.trace("Mapped to " + handler);
}
else if (logger.isDebugEnabled() && !request.getDispatcherType().equals(DispatcherType.ASYNC)) {
logger.debug("Mapped to " + executionChain.getHandler());
}
if (hasCorsConfigurationSource(handler) || CorsUtils.isPreFlightRequest(request)) {
CorsConfiguration config = (this.corsConfigurationSource != null ? this.corsConfigurationSource.getCorsConfiguration(request) : null);
CorsConfiguration handlerConfig = getCorsConfiguration(handler, request);
config = (config != null ? config.combine(handlerConfig) : handlerConfig);
executionChain = getCorsHandlerExecutionChain(request, executionChain, config);
}
return executionChain;
}
- AbstractHandlerMethodMapping:处理注解的controller
- AbstractUrlHandlerMapping:处理基础的controller
- 都继承了AbstractHandlerMapping
public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMapping implements InitializingBean {
public abstract class AbstractUrlHandlerMapping extends AbstractHandlerMapping implements MatchableHandlerMapping {
这两个类都重写了getHandlerInternal方法
Mapping.getHandlerInternal
获取HandlerMethod
// 注解的
protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
request.setAttribute(LOOKUP_PATH, lookupPath);
this.mappingRegistry.acquireReadLock();
try {
// 里面先根据请求拿到list,先添加到匹配集合,然后找到最佳匹配。get (0)
HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);
return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null);
}
finally {
this.mappingRegistry.releaseReadLock();
}
}
// 查找处理器链 // 他map的key是bean名字
protected Object getHandlerInternal(HttpServletRequest request) throws Exception {
// 获得请求的uri
String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
request.setAttribute(LOOKUP_PATH, lookupPath);
// 类的方式返回的是controller类对象,注解方式返回的是HandlerMethod对象。
Object handler = lookupHandler(lookupPath, request);
/*
protected Object lookupHandler(String urlPath, HttpServletRequest request) throws Exception {
// 这个map的key是请求uri,valye是Controller对象
Object handler = this.handlerMap.get(urlPath);
*/
if (handler == null) {
// We need to care for the default handler directly, since we need to
// expose the PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE for it as well.
Object rawHandler = null;
if ("/".equals(lookupPath)) {
rawHandler = getRootHandler();
}
if (rawHandler == null) {
rawHandler = getDefaultHandler();
}
if (rawHandler != null) {
// Bean name or resolved handler?
if (rawHandler instanceof String) {
String handlerName = (String) rawHandler;
rawHandler = obtainApplicationContext().getBean(handlerName);
}
validateHandler(rawHandler, request);
handler = buildPathExposingHandler(rawHandler, lookupPath, lookupPath, null);
}
}
return handler;
}
通过handlerMapping拿到了handlerMethod,别的hm可能拿到的是别的类型
解析参数前有pre
六、ha适配器包装参数和返回值解析器
②ds.getHandlerAdapter
回到dispatch
不同的控制器实现方式需要用不同的方式去调用
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
if (this.handlerAdapters != null) {
// handlerAdapters有3种:
/* 适配器有3个
RequestMappingHandlerAdaptor, // @RequestMapping
HttpRequestHandlerAdaptor, // 实现HttpRequestHandler的,这里不考虑
SimpleControllerHandlerAdaptor // 实现Controller接口的
// springboot里还有个HandlerrFunctionAdaptor // 支持函数向编程
为什么3种适配器2种映射器?23在前面合并了
*/
for (HandlerAdapter adapter : this.handlerAdapters) {
if (adapter.supports(handler)) {
//先调用supports
return adapter;//ha
}
}
}
throw new ServletException("没有能解析该handler的adapter。DispatcherServlet配置需要包含这个handler的ha");
}
public abstract class AbstractHandlerMethodAdapter
extends WebContentGenerator implements HandlerAdapter, Ordered {
public final boolean supports(Object handler) {
return (handler instanceof HandlerMethod && // 是HandlerMethod类型,@Controller的都是封装为HandlerMethod
supportsInternal((HandlerMethod) handler));
}
已经拿到了RequestMappingHandlerAdaptor这个ha
拿ha是用support
④ha.handle
已经拿到了方法,但是方法参数还没有,把这个过程交给ha
1 ha接口
返回ModelAndView
/** MVC框架的SPI,允许MVC处理参数
Interface that must be implemented for each handler type to handle a request.
这个接口用于允许DispatcherServlet无线扩展
DispatcherServlet通过本类判断所有安装的handlers。
handler可以是Object类型。这使其他框架的handlers融合到框架里。
HandlerAdapter的实现类也可能实现了Ordered接口,DispatcherServlet就可以按序获取
*/
public interface HandlerAdapter {
/** 当前ha是否能解析该handler。。。HandlerAdapters一般只支持一个handler类型 */
boolean supports(Object handler);
/** 本ha是否能处理 使用给定的handlers处理本请求。通过了supports()后经过这个方法
返回一个ModelAndView,名字为视图名和必要的model数据,如果request没被正确处理,返回null */
@Nullable
ModelAndView handle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception;// 要使用的handler,必须依据经过了supports()
/** 如果没有支持的handler类,返回-1
* Same contract as for HttpServlet's {@code getLastModified} method.
* @return the lastModified value for the given handler
* @see HttpServlet#getLastModified
* @see LastModified#getLastModified
*/
long getLastModified(HttpServletRequest request, Object handler);
}
调用supports()分析适配器可用后,我们就调用它的handle()方法
2 ha实现类
- RequestMappingHandlerAdaptor, // @RequestMapping
- HttpRequestHandlerAdaptor, // 实现HttpRequestHandler的,这里不考虑
- SimpleControllerHandlerAdaptor // 实现Controller接口的
//SimpleControllerHandlerAdaptor //继承了Controller接口的自定义controller就是实现了该方法
public ModelAndView handle(HttpServletRequest request,
HttpServletResponse response,
Object handler){
return ((Controller) handler).handleRequest(request, response);
}
//AbstractHandlerMethodAdapter 注解方式的
public final ModelAndView handle(HttpServletRequest request,
HttpServletResponse response,
Object handler){
return handleInternal(request, response, (HandlerMethod) handler);
}
3 ha.handleInternal()
RequestMappingHandlerAdapter.handleInternal()
// 处理@RequestMapping注解的适配器
public class RequestMappingHandlerAdapter
extends AbstractHandlerMethodAdapter
implements BeanFactoryAware, InitializingBean {
@Override
protected ModelAndView handleInternal(HttpServletRequest request,
HttpServletResponse response,
HandlerMethod handlerMethod) {
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 {
// 没有session
// No HttpSession available -> no mutex necessary
mav = invokeHandlerMethod(request, response, handlerMethod);
}
} else {
// No synchronization on session demanded at all...
// 执行目标方法,返回modelAndView
mav = invokeHandlerMethod(request, response, handlerMethod);
}
if (!response.containsHeader(HEADER_CACHE_CONTROL)) {
if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {
applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers);
}
else {
prepareResponse(response);
}
}
return mav;
}
4 ha.invokeHandlerMethod()流程
RequestMappingHandlerAdapter.invokeHandlerMethod
- 包装ServletInvocableHandlerMethod
- invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);给目标方法里设置参数解析器
- invocableMethod.setHandlerMethodReturnValueHandlers给目标方法里设置返回值解析器
- invocableMethod.invokeAndHandle(webRequest, mavContainer);
- getModelAndView 获得视图
// RequestMappingHandlerAdapter
@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);
// 参数解析器,拿到全部
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);
if (asyncManager.hasConcurrentResult()) {
Object result = asyncManager.getConcurrentResult();
mavContainer = (ModelAndViewContainer) asyncManager.getConcurrentResultContext()[0];
asyncManager.clearConcurrentResult();
LogFormatUtils.traceDebug(logger, traceOn -> {
String formatted = LogFormatUtils.formatValue(result, !traceOn);
return "Resume with async result [" + formatted + "]";
});
invocableMethod = invocableMethod.wrapConcurrentResult(result);
}
// 去处理结果值【包括视图名、转发的map】,放入mavContainer
invocableMethod.invokeAndHandle(webRequest, mavContainer);
if (asyncManager.isConcurrentHandlingStarted()) {
return null;
}
// 获得视图
return getModelAndView(mavContainer, modelFactory, webRequest);
}
finally {
webRequest.requestCompleted();
}
}
4.1 createInvocableHandlerMethod
4.2 iM.setHandlerMethodArgumentResolvers(this.argumentResolvers);
给目标方法里设置参数解析器invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);
invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);
有很多参数解析器,RequestParamMapMethodArgumentResolver
参数解析器接口:
/** 解析方法的参数 */
public interface

本文深入解析了Spring MVC框架的核心组件,包括处理器Handler、拦截器HandlerInterceptor、处理器映射HandlerMapping、处理器适配器HandlerAdapter等,以及它们在请求处理流程中的作用。还介绍了参数解析器HandlerMethodArgumentResolver和返回值处理器HandlerMethodReturnValueHandler的工作原理,特别是如何支持@ResponseBody注解的JSON响应处理。
最低0.47元/天 解锁文章
3467

被折叠的 条评论
为什么被折叠?



