请求处理流程
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lcv67AHP-1601641042113)(http://i2.bvimg.com/664434/401d58119d13ae6b.jpg)]
- HandlerAdapter是Spring MVC内部使用的,Spring MVC会把控制器和后面要介绍的HandlerInterceptor包装为HandlerAdapter。
- HandlerMapping把控制器和HandlerInterceptor包装为HandlerExecutionChain 封装了分发到对应控制器的映射规则
- ViewResolver 视图解析器
- ModelAndView 里面包含了mode 与map
HandlerAdapter HandlerMapping handler 三者的关系,HandlerAdapter 是干活的人,handler 是干活的工具
代码流程
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
int interceptorIndex = -1;
try {
ModelAndView mv;
boolean errorView = false;
try {
//1
processedRequest = checkMultipart(request);
//2
// Determine handler for the current request.
mappedHandler = getHandler(processedRequest, false);
if (mappedHandler == null || mappedHandler.getHandler() == null ) {
noHandlerFound(processedRequest, response);
return;
}
//3
// Determine handler adapter for the current request.
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// Process last-modified header, if supported by the handler.
String method = request.getMethod();
//4
boolean isGet = "GET" .equals(method);
if (isGet || "HEAD" .equals(method)) {
long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
if (logger .isDebugEnabled()) {
String requestUri = urlPathHelper.getRequestUri(request);
logger.debug( "Last-Modified value for [" + requestUri + "] is: " + lastModified);
}
if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
return;
}
}
//5
// Apply preHandle methods of registered interceptors.
HandlerInterceptor[] interceptors = mappedHandler.getInterceptors();
if (interceptors != null) {
for (int i = 0; i < interceptors.length; i++) {
HandlerInterceptor interceptor = interceptors[i];
if (!interceptor.preHandle(processedRequest, response, mappedHandler.getHandler())) {
triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null);
return;
}
interceptorIndex = i;
}
}
//6
// Actually invoke the handler.
mv = ha. handle(processedRequest, response, mappedHandler.getHandler());
// Do we need view name translation?
if (mv != null && !mv.hasView()) {
mv.setViewName(getDefaultViewName(request));
}
// Apply postHandle methods of registered interceptors.
if (interceptors != null) {
for (int i = interceptors.length - 1; i >= 0; i--) {
HandlerInterceptor interceptor = interceptors[i];
interceptor.postHandle(processedRequest, response, mappedHandler.getHandler(), mv);
}
}
}
catch (ModelAndViewDefiningException ex) {
logger.debug( "ModelAndViewDefiningException encountered", ex);
mv = ex.getModelAndView();
}
catch (Exception ex) {
Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null );
mv = processHandlerException(processedRequest, response, handler, ex);
errorView = (mv != null);
}
//7
// Did the handler return a view to render?
if (mv != null && !mv.wasCleared()) {
render(mv, processedRequest, response);
if (errorView) {
WebUtils. clearErrorRequestAttributes(request);
}
}
else {
if (logger .isDebugEnabled()) {
logger.debug( "Null ModelAndView returned to DispatcherServlet with name '" + getServletName() +
"': assuming HandlerAdapter completed request handling");
}
}
// Trigger after-completion for successful outcome.
triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null );
}
catch (Exception ex) {
// Trigger after-completion for thrown exception.
triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex);
throw ex;
}
catch (Error err) {
ServletException ex = new NestedServletException("Handler processing failed", err);
// Trigger after-completion for thrown exception.
triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex);
throw ex;
}
finally {
// Clean up any resources used by a multipart request.
if (processedRequest != request) {
cleanupMultipart(processedRequest);
}
}
}
1 .判断请求是否是上传等数据流请求
2 .根据请求携带的参数和url信息,根据相应的匹配规则找到处理请求的处理器,
注意这个处理器是HandlerExecutionChain对象,它是一个链对象,里面封装了一个handle对象,和拦截器集合对象,注意handler没有确切的类型,实际上这里的handler就 是我们在业务代码里面写的Controller,因为我们的Controller在框架层面是通过java反射机制动态调用的,所以没有确切的类型
3 .通过handler的类型找到HandlerAdapter来具体处理请求,注意第2步中getHandler
方法获取HandlerMapping,这个组件主要的作用是封装了根据请求寻找处理器的配置规则匹配规则可以是多样的,可以实现HandlerMapping实现自己的匹配器,与HandlerMappig对应的是HandlerAdapter组件,第3步就是遍历注册的HandlerAdapter,找到匹配的HandlerAdapter
4 .使用客户端缓存,如果发的请求LastModifiedTime时间戳是否最新页面。如果是,则 后续不需要在处理了
5 .应用拦截器
6 .调用handle处理请求
7 .渲染请求结果页面
HandlerMapping
HandlerMapping封装了规则与处理器(处理器链)的对应关系,初始化会将配置中的HandMapping配置载入
/** List of HandlerMappings used by this servlet */
private List<HandlerMapping> handlerMappings;
handlerMappings 初始化的过程
private void initHandlerMappings(ApplicationContext context) {
this.handlerMappings = null;
if (this.detectAllHandlerMappings) {
// Find all HandlerMappings in the ApplicationContext, including ancestor contexts.
Map<String, HandlerMapping> matchingBeans =
BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
if (!matchingBeans.isEmpty()) {
this.handlerMappings = new ArrayList<HandlerMapping>(matchingBeans.values());
// We keep HandlerMappings in sorted order.
OrderComparator.sort(this.handlerMappings);
}
}
else {
try {
HandlerMapping hm = context.getBean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class);
this.handlerMappings = Collections.singletonList(hm);
}
catch (NoSuchBeanDefinitionException ex) {
// Ignore, we'll add a default HandlerMapping later.
}
}
// Ensure we have at least one HandlerMapping, by registering
// a default HandlerMapping if no other mappings are found.
if (this.handlerMappings == null) {
this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class);
if (logger.isDebugEnabled()) {
logger.debug("No HandlerMappings found in servlet '" + getServletName() + "': using default");
}
}
}
根据规则具体匹配处理链
遍历所有HandlerMapping 看当前的请求能否匹配应用到这个处理链条
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
for (HandlerMapping hm : this.handlerMappings) {
if (logger.isTraceEnabled()) {
logger.trace(
"Testing handler map [" + hm + "] in DispatcherServlet with name '" + getServletName() + "'");
}
HandlerExecutionChain handler = hm.getHandler(request);
if (handler != null) {
return handler;
}
}
return null;
}
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 = getApplicationContext().getBean(handlerName);
}
return getHandlerExecutionChain(handler, request);
}
用请求路径lookupPath去匹配HandlerMapping里面配置的规则器MappedInterceptor
protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
HandlerExecutionChain chain =
(handler instanceof HandlerExecutionChain) ?
(HandlerExecutionChain) handler : new HandlerExecutionChain(handler);
chain.addInterceptors(getAdaptedInterceptors());
String lookupPath = urlPathHelper.getLookupPathForRequest(request);
for (MappedInterceptor mappedInterceptor : mappedInterceptors) {
if (mappedInterceptor.matches(lookupPath, pathMatcher)) {
chain.addInterceptor(mappedInterceptor.getInterceptor());
}
}
return chain;
}