从doGet、doPost方法入手,在父类FrameworkServlet中
protected final void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
@Override
protected final void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
protected final void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
long startTime = System.currentTimeMillis();
Throwable failureCause = null;
LocaleContext previousLocaleContext = LocaleContextHolder.getLocaleContext();
LocaleContext localeContext = buildLocaleContext(request);
RequestAttributes previousAttributes = RequestContextHolder.getRequestAttributes();
ServletRequestAttributes requestAttributes = buildRequestAttributes(request, response, previousAttributes);
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
asyncManager.registerCallableInterceptor(FrameworkServlet.class.getName(), new RequestBindingInterceptor());
//绑定当前线程
initContextHolders(request, localeContext, requestAttributes);
try {
//进一步处理
doService(request, response);
}
catch ...
finally {
//恢复线程到原始状态
resetContextHolders(request, previousLocaleContext, previousAttributes);
if (requestAttributes != null) {
requestAttributes.requestCompleted();
}
logResult(request, response, failureCause, asyncManager);
//发布事件通知
publishRequestHandledEvent(request, response, startTime, failureCause);
}
}
doGet、doPost方法都是调用processRequest方法,做了一些准备工作,然后交由doService方法进一步处理
DispatcherServlet重写了doService方法
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
...
Map<String, Object> attributesSnapshot = null;
if (WebUtils.isIncludeRequest(request)) {
attributesSnapshot = new HashMap<>();
Enumeration<?> attrNames = request.getAttributeNames();
while (attrNames.hasMoreElements()) {
String attrName = (String) attrNames.nextElement();
if (this.cleanupAfterInclude || attrName.startsWith(DEFAULT_STRATEGIES_PREFIX)) {
attributesSnapshot.put(attrName, request.getAttribute(attrName));
}
}
}
// 设置变量
request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, getWebApplicationContext());
request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver);
request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver);
request.setAttribute(THEME_SOURCE_ATTRIBUTE, getThemeSource());
if (this.flashMapManager != null) {
FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate(request, response);
if (inputFlashMap != null) {
request.setAttribute(INPUT_FLASH_MAP_ATTRIBUTE, Collections.unmodifiableMap(inputFlashMap));
}
request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());
request.setAttribute(FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager);
}
try {
doDispatch(request, response);
}
finally {
if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
// Restore the original attribute snapshot, in case of an include.
if (attributesSnapshot != null) {
restoreAttributesAfterInclude(request, attributesSnapshot);
}
}
}
}
做好准备工作将已经初始化的功能辅助工具变量,如localeResolver、themeResolver等设置到request属性中。doDispatch才真正进行处理请求。
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
boolean multipartRequestParsed = false;
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
try {
ModelAndView mv = null;
Exception dispatchException = null;
try {
//检测是否是文件上传
processedRequest = checkMultipart(request);
multipartRequestParsed = (processedRequest != request);
//【标记1】 从handlerMappings获取相应的handler
mappedHandler = getHandler(processedRequest);
if (mappedHandler == null) {
noHandlerFound(processedRequest, response);
return;
}
//【标记2】 从handlerAdapters获取相应的handlerAdapter
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// 是否支持last-modified
String method = request.getMethod();
boolean isGet = "GET".equals(method);
if (isGet || "HEAD".equals(method)) {
long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
return;
}
}
//调用拦截器的前置方法
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
// 真正调用handler进行请求的处理
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
//如果没返回视图,则使用默认的视图
applyDefaultViewName(processedRequest, mv);
//调用拦截器的后置方法
mappedHandler.applyPostHandle(processedRequest, response, mv);
}
catch (Exception ex) {
dispatchException = ex;
}
catch (Throwable err) {
dispatchException = new NestedServletException("Handler dispatch failed", err);
}
//【标记3】处理handler返回的结果
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
catch (Exception ex) {
triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
}
catch (Throwable err) {
triggerAfterCompletion(processedRequest, response, mappedHandler,
new NestedServletException("Handler processing failed", err));
}
finally {
if (asyncManager.isConcurrentHandlingStarted()) {
// Instead of postHandle and afterCompletion
if (mappedHandler != null) {
mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
}
}
else {
// Clean up any resources used by a multipart request.
if (multipartRequestParsed) {
cleanupMultipart(processedRequest);
}
}
}
}
【标记1】获取handler
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
if (this.handlerMappings != null) {
for (HandlerMapping mapping : this.handlerMappings) {
HandlerExecutionChain handler = mapping.getHandler(request);
if (handler != null) {
return handler;
}
}
}
return null;
}
getHandler方法主要是从handlerMappings获取相应的handler,然后封装成HandlerExecutionChain返回。
【标记2】 获取HandlerAdapter
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
if (this.handlerAdapters != null) {
for (HandlerAdapter adapter : this.handlerAdapters) {
if (adapter.supports(handler)) {
return adapter;
}
}
}
throw...
}
getHandlerAdapter方法主要是从handlerAdapters获取相应的adapter返回。
【标记3】处理handler返回的结果
private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,
@Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv,
@Nullable Exception exception) throws Exception {
boolean errorView = false;
if (exception != null) {
if (exception instanceof ModelAndViewDefiningException) {
mv = ((ModelAndViewDefiningException) exception).getModelAndView();
}
else {
Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);
mv = processHandlerException(request, response, handler, exception);
errorView = (mv != null);
}
}
// Did the handler return a view to render?
if (mv != null && !mv.wasCleared()) {
render(mv, request, response);
if (errorView) {
WebUtils.clearErrorRequestAttributes(request);
}
}
...
}
protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {
Locale locale =
(this.localeResolver != null ? this.localeResolver.resolveLocale(request) : request.getLocale());
response.setLocale(locale);
View view;
String viewName = mv.getViewName();
if (viewName != null) {
// 【标记4】通过视图名获取View.
view = resolveViewName(viewName, mv.getModelInternal(), locale, request);
if (view == null) {
throw...
}
}
else {
// 检验是否存在视图
view = mv.getView();
if (view == null) {
throw...
}
}
try {
if (mv.getStatus() != null) {
response.setStatus(mv.getStatus().value());
}
//【标记5】
view.render(mv.getModelInternal(), request, response);
}
catch...
}
protected View resolveViewName(String viewName, @Nullable Map<String, Object> model,
Locale locale, HttpServletRequest request) throws Exception {
if (this.viewResolvers != null) {
for (ViewResolver viewResolver : this.viewResolvers) {
//【标记4】通过视图名获取View
View view = viewResolver.resolveViewName(viewName, locale);
if (view != null) {
return view;
}
}
}
return null;
}
【标记4】获取View对象,以InternalResourceViewResolver为例,resolveViewName在其父类AbstractCachingViewResolver中
public View resolveViewName(String viewName, Locale locale) throws Exception {
if (!isCache()) {//没缓存就创建
return createView(viewName, locale);
}
else {
Object cacheKey = getCacheKey(viewName, locale);
View view = this.viewAccessCache.get(cacheKey);
if (view == null) {
synchronized (this.viewCreationCache) {
view = this.viewCreationCache.get(cacheKey);
if (view == null) {
// 子类进行创建
view = createView(viewName, locale);
if (view == null && this.cacheUnresolved) {
view = UNRESOLVED_VIEW;
}
if (view != null) {
this.viewAccessCache.put(cacheKey, view);
this.viewCreationCache.put(cacheKey, view);
}
}
}
}
return (view != UNRESOLVED_VIEW ? view : null);
}
}
UrlBasedViewResolver类
protected View createView(String viewName, Locale locale) throws Exception {
// 检查是否支持该视图
if (!canHandle(viewName, locale)) {
return null;
}
// 重定向处理
if (viewName.startsWith(REDIRECT_URL_PREFIX)) {
String redirectUrl = viewName.substring(REDIRECT_URL_PREFIX.length());
RedirectView view = new RedirectView(redirectUrl,
isRedirectContextRelative(), isRedirectHttp10Compatible());
String[] hosts = getRedirectHosts();
if (hosts != null) {
view.setHosts(hosts);
}
return applyLifecycleMethods(REDIRECT_URL_PREFIX, view);
}
// 转发处理
if (viewName.startsWith(FORWARD_URL_PREFIX)) {
String forwardUrl = viewName.substring(FORWARD_URL_PREFIX.length());
InternalResourceView view = new InternalResourceView(forwardUrl);
return applyLifecycleMethods(FORWARD_URL_PREFIX, view);
}
// 回到父类的createView进行调用loadView
return super.createView(viewName, locale);
}
protected View createView(String viewName, Locale locale) throws Exception {
return loadView(viewName, locale);
}
protected abstract View loadView(String viewName, Locale locale) throws Exception;
protected View loadView(String viewName, Locale locale) throws Exception {
//真正创建View
AbstractUrlBasedView view = buildView(viewName);
//交由spring管理声明周期
View result = applyLifecycleMethods(viewName, view);
return (view.checkResource(locale) ? result : null);
}
真正创建View在buildView方法
protected AbstractUrlBasedView buildView(String viewName) throws Exception {
Class<?> viewClass = getViewClass();
//创建
AbstractUrlBasedView view = (AbstractUrlBasedView) BeanUtils.instantiateClass(viewClass);
//设置前缀、后缀
view.setUrl(getPrefix() + viewName + getSuffix());
//类型设置
String contentType = getContentType();
if (contentType != null) {
view.setContentType(contentType);
}
...
return view;
}
【标记5】页面跳转
AbstractView类
public void render(@Nullable Map<String, ?> model, HttpServletRequest request,
HttpServletResponse response) throws Exception {
...
//获取整合一些属性
Map<String, Object> mergedModel = createMergedOutputModel(model, request, response);
prepareResponse(request, response);
//处理页面跳转
renderMergedOutputModel(mergedModel, getRequestToExpose(request), response);
}
InternalResourceView类
protected void renderMergedOutputModel(
Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
// 把属性设置到request中
exposeModelAsRequestAttributes(model, request);
// Expose helpers as request attributes, if any.
exposeHelpers(request);
// 获取路径
String dispatcherPath = prepareForRendering(request, response);
//拿到请求派发器
RequestDispatcher rd = getRequestDispatcher(request, dispatcherPath);
if (rd == null) {
throw...
}
if (useInclude(request, response)) {
response.setContentType(getContentType());
rd.include(request, response);
}
else {
...
rd.forward(request, response);
}
}
总结参考:SpringMVC请求流程详解