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);
}