参考:01、基础入门-SpringBoot2课程介绍_哔哩哔哩_bilibili
请求进入HttpServlet 的doGet方法
然后通过实现类org.springframework.web.servlet.FrameworkServlet#doGet()
调用 org.springframework.web.servlet.FrameworkServlet#processRequest
----》org.springframework.web.servlet.DispatcherServlet#doService
----》org.springframework.web.servlet.DispatcherServlet#doDispatch
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
代码1 mappedHandler = getHandler(processedRequest);
代码2 HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// Actually invoke the handler.
代码3 mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
}
代码1.根据映射器获取handler
getHandler(processedRequest) 就是 请求处理器映射器获取对应的handler
@Nullable
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
if (this.handlerMappings != null) {
for (HandlerMapping mapping : this.handlerMappings) {
HandlerExecutionChain handler = mapping.getHandler(request);
if (handler != null) {
return handler;
}
}
}
return null;
}
在默认情况下springmvc 会提供5个
如果是在controller层标注了@RequestMapping 那就是会使用
RequestMappingHandlerMapping
代码2.根据handler 获取处理器适配器
getHandlerAdapter(mappedHandler.getHandler()); 就是 请求处理器映射器获取对应的handler
代码3.执行controller层代码
ha.handle(processedRequest, response, mappedHandler.getHandler());
这里面有个前提就是springmvc如何获取请求入参 比如@PathVariable /@RequestParam
因为此时代码执行到了ha.handle(processedRequest, response, mappedHandler.getHandler());
此时的调用链是
org.springframework.web.servlet.HandlerAdapter#handle
----》org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter#handle
----》org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#handleInternal
----》org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#invokeHandlerMethod
protected ModelAndView invokeHandlerMethod(HttpServletRequest request,
HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
注意点1:if (this.argumentResolvers != null) {
invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);
}
注意点2: if (this.returnValueHandlers != null) {
invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);
}
注意点3: invocableMethod.invokeAndHandle(webRequest, mavContainer);
return getModelAndView(mavContainer, modelFactory, webRequest);
}
在上面的代码中里面有着注意点1argumentResolvers 这里面就是用来解析 对应的入参的
通过debug的形式可以发现里面的内容
就举例PathVariableMapMethodArgumentResolver 这里面就标识了注解parameter.getParameterAnnotation(PathVariable.class);
public class PathVariableMapMethodArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
PathVariable ann = parameter.getParameterAnnotation(PathVariable.class);
return (ann != null && Map.class.isAssignableFrom(parameter.getParameterType()) &&
!StringUtils.hasText(ann.value()));
}
/**
* Return a Map with all URI template variables or an empty map.
*/
@Override
public Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {
@SuppressWarnings("unchecked")
Map<String, String> uriTemplateVars =
(Map<String, String>) webRequest.getAttribute(
HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, RequestAttributes.SCOPE_REQUEST);
if (!CollectionUtils.isEmpty(uriTemplateVars)) {
return new LinkedHashMap<>(uriTemplateVars);
}
else {
return Collections.emptyMap();
}
}
}
然后里面还有着 注意点2返回值的returnValueHandlers
这里面的内容有着这里面的就是开头那个流程图图片里的ModeAndView对象
接下来是 注意点3 invocableMethod.invokeAndHandle(webRequest, mavContainer);
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod#invokeAndHandle
--》org.springframework.web.method.support.InvocableHandlerMethod#invokeForRequest
--》org.springframework.web.method.support.InvocableHandlerMethod#doInvoke
这里面就是通过反射然后调用controller层代码了
针对于视图解析器上,因为普遍采用的都是前后端分离了,基本都是json数据了,所以暂时不怎么了解了
标签:web,handler,spring,流程,springframework,mvc,org,getHandler,servlet From: https://www.cnblogs.com/zz0203/p/17758127.html