深入理解SpringMVC之核心组件、工作原理及相关注解

GitHub:https://github.com/JDawnF

目录

一、核心组件

1.概述:

2. MultipartResolver

MultipartResolver 接口,代码如下:

3. LocaleResolver

4. ThemeResolver

5. HandlerMapping

6. HandlerAdapter

7. HandlerExceptionResolver

8. RequestToViewNameTranslator

9. ViewResolver

10. FlashMapManager

二、SpringMVC工作原理及DispatchServlet源码解析

三、SpringMVC相关注解

一、核心组件

1.概述:

Spring MVC 一共有九大核心组件,分别是:

  • MultipartResolver

  • LocaleResolver

  • ThemeResolver

  • HandlerMapping

  • HandlerAdapter

  • HandlerExceptionResolver

  • RequestToViewNameTranslator

  • ViewResolver

  • FlashMapManager

初始化如下: 

// DispatcherServlet.java
 /** MultipartResolver used by this servlet. */
 @Nullable
 private MultipartResolver multipartResolver;
 ​
 /** LocaleResolver used by this servlet. */
 @Nullable
 private LocaleResolver localeResolver;
 ​
 /** ThemeResolver used by this servlet. */
 @Nullable
 private ThemeResolver themeResolver;
 ​
 /** List of HandlerMappings used by this servlet. */
 @Nullable
 private List<HandlerMapping> handlerMappings;
 ​
 /** List of HandlerAdapters used by this servlet. */
 @Nullable
 private List<HandlerAdapter> handlerAdapters;
 ​
 /** List of HandlerExceptionResolvers used by this servlet. */
 @Nullable
 private List<HandlerExceptionResolver> handlerExceptionResolvers;
 ​
 /** RequestToViewNameTranslator used by this servlet. */
 @Nullable
 private RequestToViewNameTranslator viewNameTranslator;
 ​
 /** FlashMapManager used by this servlet. */
 @Nullable
 private FlashMapManager flashMapManager;
 ​
 /** List of ViewResolvers used by this servlet. */
 @Nullable
 private List<ViewResolver> viewResolvers;
     
 /**
  * This implementation calls {@link #initStrategies}.
  */
 @Override
 protected void onRefresh(ApplicationContext context) {
     initStrategies(context);
 }
     
 /**
  * Initialize the strategy objects that this servlet uses.
  * <p>May be overridden in subclasses in order to initialize further strategy objects.
  */
 protected void initStrategies(ApplicationContext context) {
     // 初始化 MultipartResolver
     initMultipartResolver(context);
     // 初始化 LocaleResolver
     initLocaleResolver(context);
     // 初始化 ThemeResolver
     initThemeResolver(context);
     // 初始化 HandlerMappings
     initHandlerMappings(context);
     // 初始化 HandlerAdapters
     initHandlerAdapters(context);
     // 初始化 HandlerExceptionResolvers 
     initHandlerExceptionResolvers(context);
     // 初始化 RequestToViewNameTranslator
     initRequestToViewNameTranslator(context);
     // 初始化 ViewResolvers
     initViewResolvers(context);
     // 初始化 FlashMapManager
     initFlashMapManager(context);
 }

2. MultipartResolver

org.springframework.web.multipart.MultipartResolver ,内容类型( Content-Type )为 multipart/* 的请求的解析器接口。

例如,文件上传请求,MultipartResolver 会将 HttpServletRequest 封装成 MultipartHttpServletRequest ,这样从 MultipartHttpServletRequest 中获得上传的文件。具体的使用示例,参见 《spring-boot 上传文件 MultiPartFile 获取不到文件问题解决》

关于内容类型( Content-Type )为 multipart/* ,可以看看 《HTTP 协议之 multipart/form-data 请求分析》 文章。

MultipartResolver 接口,代码如下:

// MultipartResolver.java
 public interface MultipartResolver {
     /**
      * 是否为 multipart 请求
      */
     boolean isMultipart(HttpServletRequest request);
 ​
     /**
      * 将 HttpServletRequest 请求封装成 MultipartHttpServletRequest 对象
      */
     MultipartHttpServletRequest resolveMultipart(HttpServletRequest request) throws MultipartException;
     /**
      * 清理处理 multipart 产生的资源,例如临时文件
      *
      */
     void cleanupMultipart(MultipartHttpServletRequest request);
 }

3. LocaleResolver

org.springframework.web.servlet.LocaleResolver本地化( 国际化 )解析器接口。代码如下:

// LocaleResolver.java
 public interface LocaleResolver {
     /**
      * 从请求中,解析出要使用的语言。例如,请求头的 "Accept-Language"
      */
     Locale resolveLocale(HttpServletRequest request);
     /**
      * 设置请求所使用的语言
      */
     void setLocale(HttpServletRequest request, @Nullable HttpServletResponse response, @Nullable Locale locale);
 ​
 }

具体的使用示例,参见 《SpringMVC学习系列(8) 之 国际化》

4. ThemeResolver

org.springframework.web.servlet.ThemeResolver主题解析器接口。代码如下:

// ThemeResolver.java
 public interface ThemeResolver {
     /**
      * 从请求中,解析出使用的主题。例如,从请求头 User-Agent ,判断使用 PC 端,还是移动端的主题
      */
     String resolveThemeName(HttpServletRequest request);
 ​
     /**
      * 设置请求,所使用的主题。
      */
     void setThemeName(HttpServletRequest request, @Nullable HttpServletResponse response, @Nullable String themeName);
 }

具体的使用示例,参见 《如何使用 Spring MVC 主题》

因为现在的前端,基本和后端做了分离,所以这个功能已经越来越少用了。

5. HandlerMapping

org.springframework.web.servlet.HandlerMapping ,处理器匹配接口,根据请求( handler )获得其的处理器( handler)和拦截器们( HandlerInterceptor 数组 )。代码如下:

// HandlerMapping.java
 public interface HandlerMapping {
     String PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE = HandlerMapping.class.getName() + ".pathWithinHandlerMapping";
     String BEST_MATCHING_PATTERN_ATTRIBUTE = HandlerMapping.class.getName() + ".bestMatchingPattern";
     String INTROSPECT_TYPE_LEVEL_MAPPING = HandlerMapping.class.getName() + ".introspectTypeLevelMapping";
     String URI_TEMPLATE_VARIABLES_ATTRIBUTE = HandlerMapping.class.getName() + ".uriTemplateVariables";
     String MATRIX_VARIABLES_ATTRIBUTE = HandlerMapping.class.getName() + ".matrixVariables";
     String PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE = HandlerMapping.class.getName() + ".producibleMediaTypes";
     /**
      * 获得请求对应的处理器和拦截器们
      */
     @Nullable
     HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;
 }
  • 返回的对象类型是 HandlerExecutionChain ,它包含处理器( handler )和拦截器们( HandlerInterceptor 数组 )。简单代码如下:

    // HandlerExecutionChain.java
     /**
      * 处理器
      */
     private final Object handler;
     /**
      * 拦截器数组
      */
     @Nullable
     private HandlerInterceptor[] interceptors;
    • 注意,处理器的类型可能和我们想的不太一样,是个 Object 类型。

6. HandlerAdapter

org.springframework.web.servlet.HandlerAdapter ,处理器适配器接口。代码如下:

// HandlerAdapter.java
 public interface HandlerAdapter {
     /**
      * 是否支持该处理器
      */
     boolean supports(Object handler);
 ​
     /**
      * 执行处理器,返回 ModelAndView 结果
      */
     @Nullable
     ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
     /**
      * 返回请求的最新更新时间。
      *
      * 如果不支持该操作,则返回 -1 即可
      */
     long getLastModified(HttpServletRequest request, Object handler);
 }
  • 因为,处理器 handler 的类型是 Object 类型,需要有一个调用者来实现 handler 是怎么被使用,怎么被执行。而 HandlerAdapter 的用途就在于此。

7. HandlerExceptionResolver

org.springframework.web.servlet.HandlerExceptionResolver处理器异常解析器接口,将处理器( handler )执行时发生的异常,解析( 转换 )成对应的 ModelAndView 结果。代码如下:

// HandlerExceptionResolver.java
 public interface HandlerExceptionResolver {
     /**
      * 解析异常,转换成对应的 ModelAndView 结果
      */
     @Nullable
     ModelAndView resolveException(
             HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex);
 }

8. RequestToViewNameTranslator

org.springframework.web.servlet.RequestToViewNameTranslator ,请求到视图名的转换器接口。代码如下:

// RequestToViewNameTranslator.java
 public interface RequestToViewNameTranslator {
     /**
      * 根据请求,获得其视图名
      */
     @Nullable
     String getViewName(HttpServletRequest request) throws Exception;
 }

9. ViewResolver

org.springframework.web.servlet.ViewResolver实体解析器接口,根据视图名和国际化,获得最终的视图 View 对象。代码如下:

// ViewResolver.java
 public interface ViewResolver {
     /**
      * 根据视图名和国际化,获得最终的 View 对象
      */
     @Nullable
     View resolveViewName(String viewName, Locale locale) throws Exception;
 }

ViewResolver 的实现类比较多,例如说,InternalResourceViewResolver 负责解析 JSP 视图,FreeMarkerViewResolver 负责解析 Freemarker 视图。

10. FlashMapManager

org.springframework.web.servlet.FlashMapManager ,FlashMap 管理器接口,负责重定向时,保存参数到临时存储中。代码如下:

// FlashMapManager.java
 public interface FlashMapManager {
     /**
      * 恢复参数,并将恢复过的和超时的参数从保存介质中删除
      */
     @Nullable
     FlashMap retrieveAndUpdate(HttpServletRequest request, HttpServletResponse response);
     /**
      * 将参数保存起来
      */
     void saveOutputFlashMap(FlashMap flashMap, HttpServletRequest request, HttpServletResponse response);
 ​
 }

默认情况下,这个临时存储会是 Session 。也就是说:

  • 重定向前,保存参数到 Seesion 中。

  • 重定向后,从 Session 中获得参数,并移除。

具体使用示例,参见 《Spring MVC Flash Attribute 的讲解与使用示例》 一文。

实际场景下,使用的非常少,特别是前后端分离之后。

二、SpringMVC工作原理及DispatchServlet源码解析

参照:SpringMVC工作原理及DispatcherServlet源码解析

三、SpringMVC相关注解

参照:https://blog.csdn.net/striveb/article/details/90664375

 

 

参照:芋道源码

posted @ 2019-05-29 08:35  白晨冬阳  阅读(311)  评论(0编辑  收藏  举报