SpringMVC 处理流程

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/a58YYXG/article/details/81812692

Tomcat 收到一个请求时,透过一系列组件的执行,到达 DispatcherServlet:

DispatcherServlet.java

@Override
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
    
    ... ...
    doDispatch(request, response);
}


protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {

    HandlerExecutionChain mappedHandler = null;
    ModelAndView mv = null;

    ... ...
    
    // 1
    mappedHandler = getHandler(processedRequest);

    // 2
    HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
    
    // 3
    if (!mappedHandler.applyPreHandle(processedRequest, response))
	    return;

    // 4 
    mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

    // 5
    mappedHandler.applyPostHandle(processedRequest, response, mv);

    // 6
    processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}

1. mappedHandler = getHandler(processedRequest);

第一步,通过 Request 查找符合条件的 HandlerMapper,返回对象 HandlerExecutionChain;这是一个执行链,其中包含有符合本次 Request 的处理器 Handler(Controller)和拦截器 HandlerInterceptor。

HandlerExecutionChain.java

public class HandlerExecutionChain {

	private static final Log logger = LogFactory.getLog(HandlerExecutionChain.class);

	private final Object handler;

	@Nullable
	private HandlerInterceptor[] interceptors;

	@Nullable
	private List<HandlerInterceptor> interceptorList;

	private int interceptorIndex = -1;

    ... ...
}

2. HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

第二步,通过 Handler(Controller)获取 HandlerAdapter,获取过程其实就是判断该 Handler 是否能够被HandlerAdapter 所处理。

DispatcherServlet.java

protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
    if (this.handlerAdapters != null) {
	for (HandlerAdapter ha : this.handlerAdapters) {
	    ... logger ...
            
            // Here
            if (ha.supports(handler)) {
	        return ha;
	    }
        }
    }

    ... throw exception ...
}

HandlerAdapter.java

public interface HandlerAdapter {

	boolean supports(Object handler);

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

	long getLastModified(HttpServletRequest request, Object handler);
}

HandlerAdapter 是 SpringMVC 中真正调用 Handler(Controller)的组件,就是该接口中的第二个方法,方法中处理调用完 Handler(Controller)后返回结果 ModelAndView,DispatcherServlet 中得到结果后继续往下处理视图渲染的步骤;HandlerAdapter 的子类中有比较熟悉常用的 RequestMappingHandlerAdapter。

不过在 HandlerAdapter 调用 Handler(Controller)之前,SpringMVC 提供了灵活的插件式处理方式,所以先执行前置处理第 3 步。

3. mappedHandler.applyPreHandle(processedRequest, response)

第三步,如果该 Handler(Controller)中有对应的拦截器 HandlerInterceptor,则调用拦截器前置处理方法:

HandlerExecutionChain.java

boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
	HandlerInterceptor[] interceptors = getInterceptors();
	if (!ObjectUtils.isEmpty(interceptors)) {
		for (int i = 0; i < interceptors.length; i++) {
			HandlerInterceptor interceptor = interceptors[i];
                        // Here
			if (!interceptor.preHandle(request, response, this.handler)) {
				triggerAfterCompletion(request, response, null);
				return false;
			}
			this.interceptorIndex = i;
		}
	}
	return true;
}

4. mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

第四步,由具体的 HandlerAdapter 调用方法触发 Handler 对应的处理方法,返回结果 ModelAndView。

5. mappedHandler.applyPostHandle(processedRequest, response, mv);

第五步,如果该 Handler(Controller)中有对应的拦截器 HandlerInterceptor,则调用拦截器后置处理方法 postHandle( )。

6. processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);

最后,将 HandlerAdapter 处理后返回的 ModelAndView 结果渲染,调用对应的一些渲染组件,如 LocaleResolver (本地化)、ViewResolver (视图解析器)等。

在这一步的最后还会触发一些收尾工作,调用 HandlerInterceptor 的 afterCompletion(...)。


附:SpringMVC 处理流程图

猜你喜欢

转载自blog.csdn.net/a58YYXG/article/details/81812692