在这里插入图片描述

1:一次请求的流程

为了更好的分析相关组件,我们先来简单看下一次springmvc请求从浏览器发出http request到获取http Response这个过程都经历了哪些过程,主要如下:

  • A:发出请求
  • B:到达DispatcherServlet
  • C:通过请求信息获取处理器和拦截器
  • D:根据处理器获取对应的处理器适配器
  • E:使用处理器适配器调用处理器完处理请求,获取ModelAndView
  • F:通过ModelAndView解析生成View
  • G:渲染View,返回给客户端
    以上过程可以通过下图表示:
    在这里插入图片描述
    该图只涉及到核心的几个组件的流程,具体来说组件一共是有9个,即我们经常说的springMVC的九大核心组件,下面我们就正式开始吧!

2:文件处理组件MultipartResolver

对应的接口是org.springframework.web.multipart.MultipartResolver,处理Content-Type=multipart/*的请求,如Content-Type=multipart/form-data的文件上传请求,该接口定义如下:

// 文件解析组件,主要用于将HttpServletRequest封装为MultipartHttpServletRequest
public interface MultipartResolver {
	boolean isMultipart(HttpServletRequest request);
	MultipartHttpServletRequest resolveMultipart(HttpServletRequest request) throws MultipartException;
	void cleanupMultipart(MultipartHttpServletRequest request);
}

方法isMultipart用来判断当前的请求是否为mutipart请求,方法resolveMultipart方法用来将HttpServletRequest转换为文件的请求对象MultipartHttpServletRequest。方法cleanUpMultipart用来清理在文件处理过程中产生的临时文件。

3:本地化组件LocaleResolver

对应的接口为org.springframework.web.servlet.LocaleResolver,其源码如下:

// 用于从request请求中获取Locale信息的接口,这是i18n国际化的基础
public interface LocaleResolver {
	Locale resolveLocale(HttpServletRequest request);
	void setLocale(HttpServletRequest request, @Nullable HttpServletResponse response, @Nullable Locale locale);
}

方法resolveLocale用于从请求中解析出本地化信息。方法setLocale用于设置本地化信息。

4:主题组件ThemeResolver

对应的接口为org.springframework.web.servlet.ThemeResolver,其源码如下:

public interface ThemeResolver {
	String resolveThemeName(HttpServletRequest request);
	void setThemeName(HttpServletRequest request, @Nullable HttpServletResponse response, @Nullable String themeName);
}

方法resolveThemeName用于解析当前请求需要使用的主题,方法setThemeName用于设置要使用的主题。

5:处理器映射组件HandlerMapping

该组件相对就比较重要了,对应的接口为org.springframework.web.servlet.HandlerMapping,该组件的作用是根据请求获取对应的处理器handler,源码如下:

public interface HandlerMapping {
	@Nullable
	HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;
}

方法getHandler是用来根据请求获取对应handler的方法,其中返回对象是org.springframework.web.servlet.HanlderExecutionChain是一个封装了Hanler+Interceptor复合对象,部分源码如下:

public class HandlerExecutionChain {
	private final Object handler;
	@Nullable
	private HandlerInterceptor[] interceptors;
}

属性private final Object handler就是获取的handler,private HandlerInterceptor[] interceptors数组就是对应handler的拦截器。这里handler是Object类型原因是,有很多不同的handler所以使用object来进行接收。

6:处理器适配组件HandlerAdpater

对应的接口是org.springframework.web.servlet.HandlerAdpater,需要该组件的原因是handler各种各样,因此调用方式也不相同,为了对DispacherServlet做到透明,方便调用,因此进行了适配,那么handler一般都有哪些呢,主要有以下几种。

  • 普通的servlet
  • @RequestMapping定义的方法
  • 实现Controller接口的类
  • 实现HttpRequestHandler接口的类
    org.springframework.web.servlet.HandlerAdapter接口源码如下:
public interface HandlerAdapter {
	boolean supports(Object handler);

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

方法support(Object handler)用来判断当前handler适配器是否支持调用目标handler,方法handle(HttpServletRequest request, HttpServletResponse response, Object handler)用来调用目标handler,方法getLastModified(HttpServletRequest request, Object handler)用来获取请求目标资源的上次修改时间,如果是没有则返回-1,这里简单说下流程,如果是带有缓存的,首次请求,会返回Last-Modified响应头,则浏览器会记录该时间,下次请求时会将该值放在If-Modified-Since请求头中,服务端就可以通过该值来判断缓存是否失效,从而提高接口处理能力。

7:异常转视图组件HandlerExcetionResolver

对应接口为org.springframework.web.servlet.HanlderExceptionResolver,负责将handler适配器调用目标handler过程中发生的异常转换为ModelAndView,接口源码如下:

public interface HandlerExceptionResolver {
	@Nullable
	ModelAndView resolveException(
			HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex);
}

该接口中只有一个方法resolverException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex),返回的自然就是视图和渲染视图所需数据的对象org.springframework.web.servlet.ModelAndView

8:请求转视图名组件RequestToViewNameTranslator

对应接口org.springframework.web.servlet.RequestToViewNameTranslator,源码如下:

public interface RequestToViewNameTranslator {
	@Nullable
	String getViewName(HttpServletRequest request) throws Exception;
}

只有一个方法getViewName(HttpServletRequest request)就是从请求中获取视图名称的方法。

9:视图名转视图组件ViewResolver

对应接口org.springframework.web.servlet.ViewResolver,接口源码如下:

public interface ViewResolver {
	@Nullable
	View resolveViewName(String viewName, Locale locale) throws Exception;
}

只有一个方法resolveViewName(String viewName, Locale locale),通过视图名称和本地化对象获取视图对象org.springframework.web.servlet.View。视图有不同的种类,如jsp,freemarker,如jsp对应的视图解析对象是org.springframework.web.servlet.view.InternalResourceViewResolverfreeemarker对应的是org.springframework.web.servlet.view.freemarker.FreemarkerViewResolver

10:重定向数据管理组件FlashMapManager

对应接口org.springframework.web.servlet.FlashMapManger,用于临时存储重定向时的数据,源码如下:

public interface FlashMapManager {
	@Nullable
	FlashMap retrieveAndUpdate(HttpServletRequest request, HttpServletResponse response);

	void saveOutputFlashMap(FlashMap flashMap, HttpServletRequest request, HttpServletResponse response);
}

方法retriveAndUpdate(HttpServletRequest request, HttpServletResponse response)获取本次请求的的来源重定向请求存储的数据(简单解释下,比如请求A通过重定向到请求B,然后在请求B中就可以获取在请求A中存储的参数,并删除,个人理解,如有误,请评论留言告知!)。方法saveOutputFalshMap(FlashMap flashMap,HttpServletRequest request, HttpServletResponse response),将FlashMap中的重定向数据保存到如session等中间介质中。

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐