SpringMvc的源码解析
SpringMVC处理请求的流程源码剖析
- 接收请求。DispatcherServlet是一个Servlet,在浏览器输入url,会接收到对应的请求。
HttpServlet#service()。 - 请求分发。DispatcherServlet顾名思义,负责分发的Servlet。核心方法,
DispatcherServlet#doDispatch。 - 根据请求获取HandlerExecutionChain对象。因为handlerMapping有多个类型,我们最常用的是
RequestMappingHandlerMapping。执行AbstractHandlerMethodMapping#lookupHandlerMethod,根据request获取到对应的url,根据url从MappingRegistry#pathLookup变量中获取对应的处理器。
@Nullable
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
if (this.handlerMappings != null) {
Iterator var2 = this.handlerMappings.iterator();
while(var2.hasNext()) {
HandlerMapping mapping = (HandlerMapping)var2.next();
HandlerExecutionChain handler = mapping.getHandler(request);
if (handler != null) {
return handler;
}
}
}
return null;
}
AbstractHandlerMapping#getHandlerExecutionChain,对找到的处理器进行封装。
protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ?
(HandlerExecutionChain) handler : new HandlerExecutionChain(handler));
for (HandlerInterceptor interceptor : this.adaptedInterceptors) {
if (interceptor instanceof MappedInterceptor) {
MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor;
if (mappedInterceptor.matches(request)) {
chain.addInterceptor(mappedInterceptor.getInterceptor());
}
}
else {
chain.addInterceptor(interceptor);
}
}
return chain;
}
- 获取处理器适配器。
DispatcherServlet#getHandlerAdapter,常见的还是RequestMappingHandlerAdapter。在执行到ServletInvocableHandlerMethod#invokeAndHandle方法中,会对返回值进行处理。this.returnValueHandlers.handleReturnValue(returnValue, getReturnValueType(returnValue), mavContainer, webRequest);。我们接口中常用的json字符串返回用到的返回值处理器是RequestResponseBodyMethodProcessor,当返回类型满足AnnotatedElementUtils.hasAnnotation(returnType.getContainingClass(), ResponseBody.class) || returnType.hasMethodAnnotation(ResponseBody.class);,则会调用RequestResponseBodyMethodProcessor来对返回值处理。 - 对处理器进行前置处理,主要执行
mappedHandler.applyPreHandle(processedRequest, response)。执行HandlerExecutionChain中的处理器的preHandle方法。
boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
for (int i = 0; i < this.interceptorList.size(); i++) {
HandlerInterceptor interceptor = this.interceptorList.get(i);
if (!interceptor.preHandle(request, response, this.handler)) {
triggerAfterCompletion(request, response, null);
return false;
}
this.interceptorIndex = i;
}
return true;
}
- 执行处理器。通过获取到的HandlerAdapter,即
RequestMappingHandlerAdapter来执行RequestMappingHandlerAdapter#handleInternal。反射调用方法,得到一个ModelAndView对象。 - 对处理器进行后置处理,
mappedHandler.applyPostHandle(processedRequest, response, mv);。执行HandlerExecutionChain中的处理器的postHandle方法。 - 对处理器进行异常处理,
triggerAfterCompletion(processedRequest, response, mappedHandler, ex)。 - 处理分发结果,渲染视图。
DispatcherServlet#processDispatchResult。渲染视图,DispatcherServlet#render->AbstractView#render。
SpringMvc组件初始化的流程解析
- servlet对象初始化,只有在第一次访问的时候执行一次。 所以DispatcherServlet的初始化是在应用第一次处理web请求的时候。
DispatcherServlet初始化。执行父类GenericServlet#init()。核心方法是DispatcherServlet#initStrategies。
protected void initStrategies(ApplicationContext context) {
// 多文件上传的组件
initMultipartResolver(context);
// 初始化本地语言环境
initLocaleResolver(context);
// 初始化模板处理器
initThemeResolver(context);
// 初始化HandlerMapping
initHandlerMappings(context);
// 初始化参数适配器
initHandlerAdapters(context);
// 初始化异常拦截器
initHandlerExceptionResolvers(context);
// 初始化视图预处理器
initRequestToViewNameTranslator(context);
// 初始化视图转换器
initViewResolvers(context);
// 初始化 FlashMap 管理器
initFlashMapManager(context);
}