Spring MVC —MVC框架普遍关注的问题

MVC 模式与框架

Spring MVC—MVC框架普遍关注的问题

MVC 模式

Java Web 应用的结构经历了 Model1 和 Model2 两个时代。在 Model1 模式下,整个 Web 应用几乎全部用JSP页面组成,只用少量的JavaBean来处理数据库连接、访问等操作。从工程化角度来看,JSP 不但充当了表现层角色,还充当了控制器角色,将控制逻辑和表现逻辑混杂在一起,导致代码重用率极低,使得应用极难扩展和维护。

Model2 已经是基于MVC架构的设计模式。在 Model2 中,Servlet 作为控制器,负责接收客户端发送的请求,调用后端的JavaBean(业务逻辑组件)来处理业务逻辑并根据处理结果转发到相应的JSP页面处理显示逻辑。在 Model2 模式下,模型(Model)由 JavaBean 充当,视图(View)由JSP页面充当,而控制器则由 Servlet 充当

Spring MVC—MVC框架普遍关注的问题

  • Model:由 JavaBean 充当,所有的业务逻辑、数据库访问都在Model中实现;
  • View:由 JSP 充当,负责收集用户请求参数并将应用处理结果、状态数据呈现给用户;
  • Controller:由 Servlet 充当,作用类似于调度员,即所有用户请求都发送给 Servlet,Servlet 调用 Model 来处理用户请求,并根据处理结果调用 JSP 来呈现结果;或者Servlet直接调用JSP将应用处理结果展现给用户。

MVC 框架

Struts是全世界最早的MVC框架,其与WebWork分娩出的Struts2拥有众多优秀的设计,而且吸收了传统的Struts和WebWork两者的精华,曾一度是MVC框架中的王者。但是,与SpringMVC相比,Struts2又显得如此笨重、难用。与此同时,随着Spring的广泛应用和开发者对轻量级框架的不懈追求,SpringMVC逐渐成为MVC框架中新的王者。

关注于业务逻辑的处理是MVC框架的终极目标。无论是昔日的Struts2还是今天的SpringMVC,它们的差别更多体现在设计上的优劣与细腻

作为一个MVC框架,它们都会封装并提供一些基本的组件和功能以便解放程序员的双手,比如:

  • 分发请求的前端控制器(Struts2中的StrutsPrepareAndExecuteFilter和SpringMVC中的DispatcherServlet);
  • 处理请求的业务控制器(Struts2中的Action和SpringMVC中的Controller);
  • 请求URI与请求处理方法的匹配(Struts2中的ActionMapper和SpringMVC中的HandlerMapping);
  • 请求处理方法的调用(Struts2中的ActionProxy和SpringMVC中的HandlerAdapter);
  • 类型转换问题 —— 前后台数据的流转;
  • 数据校验;
  • 异常配置;
  • 国际化和标签库;
  • 文件上传/下载;

Spring MVC 核心组件与执行流程

spring mvc基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,很好地实现了MVC架构模式的思想并将web层进行职责解耦。

Spring MVC—MVC框架普遍关注的问题

SpringMVC 执行流程

Spring MVC—MVC框架普遍关注的问题

  1. 用户向服务器发送请求,请求被Spring MVC的前端控制器DispatcherServlet截获;
  2. DispatcherServlet对请求URL(统一资源定位符)进行解析,得到URI(请求资源标识符)。然后根据该URI,调用HandlerMapping获得该Handler配置的所有相关对象,包括Handler对象以及Handler对象对应的拦截器,这些对象会被封装到一个 HandlerExecutionChain对象 当中返回;
  3. DispatcherServlet根据获得的Handler,选择一个合适的HandlerAdapter。一个HandlerAdapter会被用于处理多种(一类)Handler,并调用Handler实际处理请求的方法;
  4. 在调用Handler实际处理请求的方法之前,HandlerAdapter 首先会结合用户配置对请求消息进行转换(例如,将JSON/XML请求消息转换成一个Java对象),然后通过DataBinder将请求中的模型数据绑定到Handler(Controller)对应的处理方法的参数中。在消息转换和数据绑定过程中,Spring MVC会做一些额外的处理,比如数据类型转换、数据格式化工作和数据合法性校验等;
  5. Handler调用业务逻辑组件完成对请求的处理后,向DispatcherServlet返回一个ModelAndView对象,ModelAndView对象中应该包含视图名或者视图名和模型;
  6. DispatcherServlet根据返回的ModelAndView对象,选择一个合适的ViewResolver(视图解析器)返回给DispatcherServlet;
  7. DispatcherServlet调用视图解析器ViewResolver结合Model来渲染视图View;
  8. DispatcherServlet将视图渲染结果返回给客户端。

SpringMVC的消息转换器机制:HttpMessageConveter

在请求消息到达SpringMVC和响应消息从SpringMVC出去的过程中就存在一个消息转换的问题,即请求消息(字符串)到Java对象的转换问题

SpringMVC中可以使用@RequestBody和@ResponseBody两个注解分别完成请求消息到对象和对象到响应消息的转换,而底层这种灵活的消息转换机制就是HttpMessageConverter支持的。

SpringMVC的数据绑定组件:DataBinder

上一节提到的SpringMVC的消息转换器机制HttpMessageConveter就是在SpringMVC的数据绑定组件DataBinder的基础上实现的。在HandlerAdapter调用Handler中具体的方法处理请求前,HandlerAdapter会根据请求方法签名的不同,将请求消息中的信息以一定的方式转换并绑定到请求方法的参数中以便请求的处理。也就是说,在请求消息到达真正调用处理方法的这一段时间内,SpringMVC还会完成很多其它的工作,包括请求信息的转换、数据转换、数据格式化以及数据校验等等。事实上,SpringMVC会通过反射机制对目标处理方法的签名进行分析,并将请求消息绑定到处理方法的参数中

数据绑定的核心部件是DataBinder,其机制如下

Spring MVC—MVC框架普遍关注的问题

Spring MVC框架将ServletRequest对象及其处理方法的参数对象实例传递给DataBinder,DataBinder调用装配在Spring Web 上下文中的ConversionService组件进行数据类型转换、数据格式化工作,并将ServletRequest中的消息填充到参数对象中去。然后,再调用Validator组件对已经绑定了请求消息数据的参数对象进行数据合法性校验,并最终生成数据绑定结果BindingResult对象

SpringMVC与Struts2间的区别

SpringMVC与Struts2是当今最为流行的两个Java Web MVC框架。在本文开头,我们概述了MVC模式和框架。本节,笔者将以以下七个方面进一步总结SpringMVC与Struts2间的一些区别。

请求处理

  • Struts2是类级别的拦截,一个Action对应一个request上下文;而SpringMVC是方法级别的拦截,一个方法对应一个request上下文。特别地,在SpringMVC中,由于请求处理方法和URI对应,所以SpringMVC从架构上本身就很容易实现RESTful URL。相比而言,Struts2 则实现起来要相对费劲,因为虽然Struts2中Action的一个方法可以对应一个URL,但是其类属性却被所有方法共享,这就导致无法用注解或其他方式标识请求处理方法了。
  • SpringMVC的方法之间基本上是独立的,各个方法独享Request、Response数据,并且请求数据通过参数获取、处理结果通过ModelMap交回给框架,因此方法之间不共享变量;而Struts2就搞的就比较乱,虽然方法之间也是独立的,但是一个Action对应一个request上下文(每次来了请求就创建一个Action),也就是说其所有Action变量是共享的,这虽然不会影响程序运行,但却给我们编码读程序时带来麻烦。
  • Struts2需要针对每个request进行封装并把request,session等servlet生命周期的变量封装成一个一个Map供给Action使用,同时保证线程安全,所以在原则上,是比较耗费内存的;而由于SpringMVC是方法级别的拦截,各个方法独享Request、Response数据,因此本身就是线程安全的。

拦截器机制

  • Struts2和SpringMVC的拦截器机制均是对AOP理念的应用,但是二者的实现机制大不相同:Struts2的interceptor机制是通过代理机制(ActionProxy)+责任链模式实现的,而SpringMVC的interceptor机制实现比较简单,其通过循环的方式在handler处理请求前后分别调用preHandle()方法和postHandle()方法对请求和响应进行处理,与Spring AOP、责任链模式等基本无关。

集中访问点

  • SpringMVC的入口是servlet,而Struts2的入口是filter,这就导致了二者的机制不同,这里就牵涉到Servlet和Filter的区别了。

对Ajax的支持

  • SpringMVC集成了Ajax,使用非常方便,只需一个注解@ResponseBody就可以实现,然后直接返回响应文本即可;而Struts2拦截器集成了Ajax,在Action中处理时一般必须安装插件或者自己写代码集成进去,使用起来也相对不方便。

与Spring的整合

  • Spring MVC可以和Spring无缝整合,在项目的管理和安全方面也比Struts2要好(当然Struts2也可以通过不同的目录结构和相关配置做到SpringMVC一样的效果,但是需要xml配置的地方不少);而Struts2需要专门的插件来完成对Spring的整合。

数据验证

  • SpringMVC验证支持JSR303,处理起来相对更加灵活方便;而Struts2验证比较繁琐,感觉太烦乱。

配置和效率

  • SpringMVC开发效率和性能高于Struts2,并且SpringMVC可以认为是100%零配置。

由于篇幅过长,关于Spring MVC 的XML配置与注解配置和使用注解完成请求参数绑定就不在本篇中分享了,大家可以关注下我,获取下一篇关于Spring MVC的文章分享。

此外我还整理了一些互联网公司java程序员在面试中涉及到的绝大部分架构面试题及答案做成了文档和架构视频资料免费分享给大家(包括Dubbo、Redis、Netty、zookeeper、Spring cloud、分布式、高并发等架构技术资料)也可以关注获得更多的面试资料,节省大家收集的时间!

获取资料的方式:进群 571617441 即可领取

Spring MVC—MVC框架普遍关注的问题

猜你喜欢

转载自blog.csdn.net/weixin_44699571/article/details/88751236