Spring源码阅读(十)—SpringMVC的处理逻辑
本文主要整理了DispatchServlet进行请求逻辑处理部分的具体实现流程
个人主页:tuzhenyu’s page
原文地址:Spring源码阅读(十)—SpringMVC的处理逻辑
DispatcherServlet逻辑处理
- Web应用启动经过了ServletContextListener初始化和DispatcherServlet初始化,具体的逻辑处理由DispatcherServlet实现.DispatcherServlet类继承HttpServlet类,所以请求经由Servlet容器转发到DispatcherServlet,由DispatcherServlet类的doGet()方法或者doPost()方法处理;
protected final void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.processRequest(request, response);
}
protected final void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.processRequest(request, response);
}
- DispatcherServlet类的doGet()方法和doPost()方法并未对请求进行具体处理而是委托给processRequest()方法进行具体的处理.processRequest()方法和processRequest()方法调用的doService()方法只是处理请求前的准备工作.
protected final void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
long startTime = System.currentTimeMillis();
Object failureCause = null;
LocaleContext previousLocaleContext = LocaleContextHolder.getLocaleContext();
LocaleContext localeContext = this.buildLocaleContext(request);
RequestAttributes previousAttributes = RequestContextHolder.getRequestAttributes();
ServletRequestAttributes requestAttributes = this.buildRequestAttributes(request, response, previousAttributes);
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
asyncManager.registerCallableInterceptor(FrameworkServlet.class.getName(), new FrameworkServlet.RequestBindingInterceptor(null));
this.initContextHolders(request, localeContext, requestAttributes);
try {
this.doService(request, response);
} catch (ServletException var17) {
failureCause = var17;
throw var17;
} catch (IOException var18) {
failureCause = var18;
throw var18;
} catch (Throwable var19) {
failureCause = var19;
throw new NestedServletException("Request processing failed", var19);
} finally {
this.resetContextHolders(request, previousLocaleContext, previousAttributes);
if(requestAttributes != null) {
requestAttributes.requestCompleted();
}
if(this.logger.isDebugEnabled()) {
if(failureCause != null) {
this.logger.debug("Could not complete request", (Throwable)failureCause);
} else if(asyncManager.isConcurrentHandlingStarted()) {
this.logger.debug("Leaving response open for concurrent processing");
} else {
this.logger.debug("Successfully completed request");
}
}
this.publishRequestHandledEvent(request, response, startTime, (Throwable)failureCause);
}
}
由doService()方法调用的doDispatch()方法是请求处理的核心所在,进行了请求处理的整个流程.
MultipartContent类型的request处理,将request转换成MutipartHttpServletRequest类型的request;
根据HandlerMapping和request信息寻找对应的Handler,返回HandlerExecutionChain调用链条
从HandlerExecutionChain获取系统定义的拦截器的preHandler方法调用
激活handler对请求进行处理并返回视图
从HandlerExecutionChain获取系统定义的拦截器的postHandler方法调用
根据视图跳转具体页面
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
boolean multipartRequestParsed = false;
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
try {
try {
ModelAndView err = null;
Object dispatchException = null;
try {
processedRequest = this.checkMultipart(request);
multipartRequestParsed = processedRequest != request;
mappedHandler = this.getHandler(processedRequest);
if(mappedHandler == null || mappedHandler.getHandler() == null) {
this.noHandlerFound(processedRequest, response);
return;
}
HandlerAdapter err1 = this.getHandlerAdapter(mappedHandler.getHandler());
String method = request.getMethod();
boolean isGet = "GET".equals(method);
if(isGet || "HEAD".equals(method)) {
long lastModified = err1.getLastModified(request, mappedHandler.getHandler());
if(this.logger.isDebugEnabled()) {
this.logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);
}
if((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) {
return;
}
}
if(!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
err = err1.handle(processedRequest, response, mappedHandler.getHandler());
if(asyncManager.isConcurrentHandlingStarted()) {
return;
}
this.applyDefaultViewName(processedRequest, err);
mappedHandler.applyPostHandle(processedRequest, response, err);
} catch (Exception var20) {
dispatchException = var20;
} catch (Throwable var21) {
dispatchException = new NestedServletException("Handler dispatch failed", var21);
}
this.processDispatchResult(processedRequest, response, mappedHandler, err, (Exception)dispatchException);
} catch (Exception var22) {
this.triggerAfterCompletion(processedRequest, response, mappedHandler, var22);
} catch (Throwable var23) {
this.triggerAfterCompletion(processedRequest, response, mappedHandler, new NestedServletException("Handler processing failed", var23));
}
} finally {
if(asyncManager.isConcurrentHandlingStarted()) {
if(mappedHandler != null) {
mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
}
} else if(multipartRequestParsed) {
this.cleanupMultipart(processedRequest);
}
}
}
doDispatch()方法调用getHandler()方法从HandlerMapping映射中返回一个调用链对象
HandlerMapping一般是在servlet-dispatch.xml配置文件中通过标签进行映射定义,在Spring启动的时候会在DispatchServlet初始化的时候进行初始化,它的初始化方式主要依赖于AbstractHandlerMethodMapping这个抽象类,利用initHandlerMethods(..)方法获取所有Spring容器托管的bean,然后调用isHandler(..)看是否是@Controller注解修饰的bean,之后调用detectHandlerMethods(..)尝试去解析bean中的方法,也就是去搜索@RequestMapping注解修饰的方法,然后将url和方法绑定注册在HandlerMapping中的一个map映射表中
调用getHandler()方法 ,从映射列表中根据url path返回一个具体的HandlerMethod,然后调用getHandlerExecutionChain构造成一个HandlerExecutionChain,将工程中定义的拦截器和HandlerMethod一起封装在调用链中.
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
Iterator var2 = this.handlerMappings.iterator();
HandlerExecutionChain handler;
do {
if(!var2.hasNext()) {
return null;
}
HandlerMapping hm = (HandlerMapping)var2.next();
if(this.logger.isTraceEnabled()) {
this.logger.trace("Testing handler map [" + hm + "] in DispatcherServlet with name \'" + this.getServletName() + "\'");
}
handler = hm.getHandler(request);
} while(handler == null);
return handler;
}
public final HandlerExecutionChain getHandler(PortletRequest request) throws Exception {
Object handler = this.getHandlerInternal(request);
if(handler == null) {
handler = this.getDefaultHandler();
}
if(handler == null) {
return null;
} else {
if(handler instanceof String) {
String handlerName = (String)handler;
handler = this.getApplicationContext().getBean(handlerName);
}
return this.getHandlerExecutionChain(handler, request);
}
}
protected abstract Object getHandlerInternal(PortletRequest var1) throws Exception;
protected HandlerExecutionChain getHandlerExecutionChain(Object handler, PortletRequest request) {
if(handler instanceof HandlerExecutionChain) {
HandlerExecutionChain chain = (HandlerExecutionChain)handler;
chain.addInterceptors(this.getAdaptedInterceptors());
return chain;
} else {
return new HandlerExecutionChain(handler, this.getAdaptedInterceptors());
}
}
- 调用getHandlerAdapter(Object handler)方法根据Handler获取对应的适配器,默认适配器有系统定义的三种HttpRequestHandlerAdapter,SimpleControllerHandlerAdapter,AnnotationMethodHandlerAdapter;
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
Iterator var2 = this.handlerAdapters.iterator();
HandlerAdapter ha;
do {
if(!var2.hasNext()) {
throw new ServletException("No adapter for handler [" + handler + "]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
}
ha = (HandlerAdapter)var2.next();
if(this.logger.isTraceEnabled()) {
this.logger.trace("Testing handler adapter [" + ha + "]");
}
} while(!ha.supports(handler));
return ha;
}
从拦截链中获所有的拦截器,并遍历调用其preHandler()方法
调用HandlerAdapter.handle(…)得到一个ModelAndView对象,里面封装了数据对象及具体的View对象
从拦截链中获所有的拦截器,并遍历调用其postHandler()方法
调用processDispatchResult处理结果,相应给客户端。
结论
DispatcherServlet逻辑处理主要是通过调用doDispatch()方法实现的,在该方法中主要先后完成了根据request请求从HandlerMapping中获取Handler映射并同拦截器一起封装成拦截链;根据Handler获取对应的适配器Adapter;从拦截链中获取所有注册的拦截器并执行其preHandler方法;调用适配器执行具体的请求处理逻辑;从拦截链中获取所有注册的拦截器并执行其postHandler方法;将返回的ModlerAndeView对象进行页面跳转处理.