谈谈你对Spring MVC中的九大组件的理解?

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 一位应届毕业生被问到这样一道面试题,说谈谈你对Spring MVC中的九大组件的理解。今天,我给大家分享一下我的理解。

一位应届毕业生被问到这样一道面试题,说谈谈你对Spring MVC中的九大组件的理解。


今天,我给大家分享一下我的理解。

1、Spring MVC九大组件

f8d8dfb278dab2f85263590c7777790b.jpg

使用Spring MVC框架时,它的主要入口是DispatcherServlet类,Spring MVC子容器初始化时,会调用DispatcherServlet的onRefresh()方法,而onRefresh()方法只做了一件事,就是调用initStrategies()方法来初始化Spring MVC的九大组件,如源码所示:

protected void onRefresh(ApplicationContext context) {    
  this.initStrategies(context);
}
protected void initStrategies(ApplicationContext context) {    
  this.initMultipartResolver(context);    
  this.initLocaleResolver(context);    
  this.initThemeResolver(context);    
  this.initHandlerMappings(context);    
  this.initHandlerAdapters(context);    
  this.initHandlerExceptionResolvers(context);    
  this.initRequestToViewNameTranslator(context);    
  this.initViewResolvers(context);    
  this.initFlashMapManager(context);
}

顾名思义,initStrategies()方法直译过来就是初始化策略,Spring MVC把九大组件设计成九大策略,其实就是为了明确各个组件的职责,达到解耦的目的。

d9f707b597013aaae12a29c9e859e794.jpg

Spring MVC的九大组件按照初始化顺序分别为:MultipartResolver多文件上传组件、LocaleResolver多语言支持组件、ThemeResolver主题模板处理组件、HandlerMappings URL映射组件、HandlerAdapters业务逻辑适配组件、HandlerExceptionResolvers异常处理组件、RequestToViewNameTranslator视图名称提取组件、ViewResolvers视图渲染组件和FlashMapManager闪存管理组件。


下面给大家详细分析一下,每个组件的功能和职责。


1、MultipartResolver 多文件上传组件。

8f6b232c0ffb5738af28e19a08d71e49.jpg

用于支持多文件上传,如代码所示:

<form method="post" enctype="multipart/form-data" >
       <input type="file"/>
     <input type="file"/>
     <input type="file"/>
     <button type="submit">上传</button>
</form>

主要逻辑就是将enctype为"multipart/form-data"的表单request请求包装成MultipartHttpServletRequest。程序员在开发的时候,只需要调用MultipartHttpServletRequest的 getFile()方法,就可以获取客户端上传的文件列表了。


2、LocaleResolver多语言支持组件。

876964ee3c0d178db77c6fc303c53958.jpg

用于支持国际化多语言切换,LocaleResolver的主要作用就是从 request 中解析出 local 参数的值,如源码所示:

public interface LocaleResolver {    
  Locale resolveLocale(HttpServletRequest request);    
  void setLocale(HttpServletRequest request, HttpServletResponse response, Locale local);}
}

resolveLocale()方法是从 request 中解析出 local,setLocale()方法是将指定的 local 值设置到 request 中。而 local 大多数情况下都是用来做国际化处理的,配合多语言字典properties来使用,例如中国的Local值为zh_CN。


3、ThemeResolver主题模板处理组件。

9ee3ccc04cd77848a0bf3b665f4fc966.jpg

主要用于支持Web页面的多主题风格。可以通过ThemeResolver来读取和解析页面主题样式配置。实现原理和LocaleResolver类似,也是配置一套 properties 文件,根据不同参数来切换读取;当然,使用ThemeResolver也是可以实现国际化。如源代码所示:

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

它的主要方法也和LocaleResolver类似,一个从request提取主题名称的方法,一个设定主题名称的方法。


4、HandlerMappingURL映射组件。

38ed3129a43305b2b7fadcab6c434ed6.jpg

主要是用来保存Url和业务逻辑的对应关系,它本质上就是一个Map,Key为URL值就是对应Controller中配置了@RequestMapping注解的方法。但是在Spring源码中,被封装成了一个HandlerMapping对象。然后,每个HandlerMapping对象都被缓存在一个List中。如源码所示:

private List<HandlerMapping> handlerMappings;
private void initHandlerMappings(ApplicationContext context) {
   this.handlerMappings = null;
   if (this.detectAllHandlerMappings) {
      Map<String, HandlerMapping> matchingBeans =
            BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
      if (!matchingBeans.isEmpty()) {
         this.handlerMappings = new ArrayList<>(matchingBeans.values());
         AnnotationAwareOrderComparator.sort(this.handlerMappings);
      }
   }
   ...
}

5、HandlerAdapter业务逻辑适配组件。

fdd7428cd7a69c609c886930233568d8.jpg

主要功能是动态解析参数以及动态适配业务逻辑对应的Handler,如源码所示:

public interface HandlerAdapter {    
  boolean supports(Object handler);    
  ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;    
  long getLastModified(HttpServletRequest request, Object handler);
}

在HandlerAdapter中提供了一个叫做handle()这样一个方法,第三个参数 Object handler 第三个参数其实就是业务处理器。在DispatcherServlet中的doDispath()方法中被调用。而handler对象就是根据用户请求的Url从HandlerMapping获取的HandlerMapiping对象。

712910b062308fc25fcc487bcc3f09ac.jpg

在HandlerApdater的handle()方法中,首先会动态解析用户传过来的参数,并完成数据类型转化。然后,反射调用HandlerMapiping封装的Controller中的方法,最后,将调用方法的返回结果统一封装为ModelAndView。


6、HandlerExceptionResolver异常处理组件。

b5219da719e6cdb93da4527ece7e927d.jpg

主要用于拦截对不同异常的个性化处理,Spring可以给不同的异常配置不同的ModelAndView,HandlerExceptionResolver根据异常类型,的将处理封装为一个ModelAndView从而将异常信息转换为更加友好的Web页面展示,如源码所示:

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

HandlerExceptionResolver组件只有一个方法,就是将异常解析为ModelAndView。

8f51d042baee9047d45f5bb940537101.jpg

当然,HandlerExceptionResolver自己发生异常或者在异常页面渲染过程中发生异常HandlerExceptionResolver不会处理。Spring可以配置一个全局的500页面或者404页面来处理这个问题。


7、RequestToViewNameTranslator视图名称提取组件。

fb5fcf21913b37a225452bcdd1c78533.jpg

这个组件的主要功能是可从request中提取viewName。这个viewName设置在url参数上,也可以设置在request的header上。如源码所示:

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

这个其实还是挺有意思的,就是将 request 请求转换为视图名称。它只有一个getViewName()方法。


8、ViewResolvers视图渲染组件。

876397e1954a48461cb81e3c091ebdeb.jpg

它的作用相当于模板引擎,就是根据视图名称找到视图对应的模板文件,然后进行解析,如源码所示:

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

ViewResolvers组件只有一个resolveViewName()方法,


我们看到resolveViewName()方法有两个参数。

d3f1367d42ec2d438aff6b4d361851c8.jpg

第一个参数viewName,是String类型,它其实就是视图名称,对应的就是模板文件的名称。第二个参数local,前面我们讲过代表的是本地语言环境,可以用来做国际化。


resolveViewName()方法的放回值是一个View对象。而View对象就是用来渲染页面的,也就是说将程序返回的结果填入到具体的模板里面,生成具体的视图文件,比如:jsp,ftl,html 等等。


9、FlashMapManage闪存管理组件。

498f287043ff45aba0d57517c631287c.jpg

它相当于一个参数缓存器,用来保证请求跳转过程中参数不丢失,和Struts 2中的ValueStack值栈非常类似。主要是 redirect重定向的时候,参数传递会丢失,FlashMapManage就能大显身手,可以做到Redirect重定向和Forward转发同样的效果,如源码所示:

public interface FlashMapManager {    
FlashMap retrieveAndUpdate(HttpServletRequest request, HttpServletResponse response);   
void saveOutputFlashMap(FlashMap flashMap, HttpServletRequest request, HttpServletResponse response);
}

FlashMapManage主要有两个方法,

9ce6f954f8bb43df18d3e6d488b5c281.jpg

retrieveAndUpdate()方法是用来恢复参数的,而且对于恢复过的和超时的参数都会被删除掉。saveOutputFlashMap() 这个方法是用来保存参数的。


FlashMapManager默认会将参数保存在 Session 中,在日常开发中,如果不想将参数暴露在 Url路径中,那就可以在请求转发时,在参数中添加@RedirectAttributes注解将参数缓存,然后在下一个处理器中就可以获取到。


以上就是我对Spring MVC中的九大组件的理解。

33aa0a60ba7299989fe0c54c314885e8.jpg

需要注意的是ModelAndView和View并不属于MVC的九大组件之中,ModelAndView只是对ViewName和Model的封装,然后作为返回值把信息反馈给用户。并没有包含任何执行逻辑。而View只是对模板文件的封装,它是用作参数来传递。


完整版面试资料和答案以及PDF文档 :

9106b97c16b34d06af118b23d081cde9.gif

相关文章
|
6天前
|
缓存 前端开发 Java
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
Soring Boot的起步依赖、启动流程、自动装配、常用的注解、Spring MVC的执行流程、对MVC的理解、RestFull风格、为什么service层要写接口、MyBatis的缓存机制、$和#有什么区别、resultType和resultMap区别、cookie和session的区别是什么?session的工作原理
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
|
30天前
|
Java 数据库连接 Spring
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
文章是关于Spring、SpringMVC、Mybatis三个后端框架的超详细入门教程,包括基础知识讲解、代码案例及SSM框架整合的实战应用,旨在帮助读者全面理解并掌握这些框架的使用。
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
|
1月前
|
人工智能 自然语言处理 Java
Spring AI,Spring团队开发的新组件,Java工程师快来一起体验吧
文章介绍了Spring AI,这是Spring团队开发的新组件,旨在为Java开发者提供易于集成的人工智能API,包括机器学习、自然语言处理和图像识别等功能,并通过实际代码示例展示了如何快速集成和使用这些AI技术。
Spring AI,Spring团队开发的新组件,Java工程师快来一起体验吧
|
1月前
|
XML JSON 数据库
SpringMVC入门到实战------七、RESTful的详细介绍和使用 具体代码案例分析(一)
这篇文章详细介绍了RESTful的概念、实现方式,以及如何在SpringMVC中使用HiddenHttpMethodFilter来处理PUT和DELETE请求,并通过具体代码案例分析了RESTful的使用。
SpringMVC入门到实战------七、RESTful的详细介绍和使用 具体代码案例分析(一)
|
1月前
|
前端开发 应用服务中间件 数据库
SpringMVC入门到实战------八、RESTful案例。SpringMVC+thymeleaf+BootStrap+RestFul实现员工信息的增删改查
这篇文章通过一个具体的项目案例,详细讲解了如何使用SpringMVC、Thymeleaf、Bootstrap以及RESTful风格接口来实现员工信息的增删改查功能。文章提供了项目结构、配置文件、控制器、数据访问对象、实体类和前端页面的完整源码,并展示了实现效果的截图。项目的目的是锻炼使用RESTful风格的接口开发,虽然数据是假数据并未连接数据库,但提供了一个很好的实践机会。文章最后强调了这一章节主要是为了练习RESTful,其他方面暂不考虑。
SpringMVC入门到实战------八、RESTful案例。SpringMVC+thymeleaf+BootStrap+RestFul实现员工信息的增删改查
|
1月前
|
Java Spring
Spring的AOP组件详解
该文章主要介绍了Spring AOP(面向切面编程)组件的实现原理,包括Spring AOP的基础概念、动态代理模式、AOP组件的实现以及Spring选择JDK动态代理或CGLIB动态代理的依据。
Spring的AOP组件详解
|
1月前
|
JSON 前端开发 Java
Spring MVC返回JSON数据
综上所述,Spring MVC提供了灵活、强大的方式来支持返回JSON数据,从直接使用 `@ResponseBody`及 `@RestController`注解,到通过配置消息转换器和异常处理器,开发人员可以根据具体需求选择合适的实现方式。
87 4
|
1月前
|
XML 前端开发 Java
Spring MVC接收param参数(直接接收、注解接收、集合接收、实体接收)
Spring MVC提供了灵活多样的参数接收方式,可以满足各种不同场景下的需求。了解并熟练运用这些基本的参数接收技巧,可以使得Web应用的开发更加方便、高效。同时,也是提高代码的可读性和维护性的关键所在。在实际开发过程中,根据具体需求选择最合适的参数接收方式,能够有效提升开发效率和应用性能。
70 3
|
1月前
|
XML 前端开发 Java
Spring MVC接收param参数(直接接收、注解接收、集合接收、实体接收)
Spring MVC提供了灵活多样的参数接收方式,可以满足各种不同场景下的需求。了解并熟练运用这些基本的参数接收技巧,可以使得Web应用的开发更加方便、高效。同时,也是提高代码的可读性和维护性的关键所在。在实际开发过程中,根据具体需求选择最合适的参数接收方式,能够有效提升开发效率和应用性能。
67 2
|
27天前
|
Java 开发工具 Spring
【Azure 事件中心】azure-spring-cloud-stream-binder-eventhubs客户端组件问题, 实践消息非顺序可达
【Azure 事件中心】azure-spring-cloud-stream-binder-eventhubs客户端组件问题, 实践消息非顺序可达