目录
为什么使用Spring MVC?(SpringMVC与Servlet的比较)?Spring MVC框架特点?
Spring MVC介绍
(模型Model、视图View、控制器Controller)
Spring MVC框架是以请求为驱动,围绕Servlet设计,将请求发给控制器,然后通过模型对象,分派器来展示请求结果视图。其中核心类是DispatcherServlet,它是一个Servlet,顶层是实现的Servlet接口。
(1)控制器
一般负责准备一个Map模型、填充数据、返回一个合适的视图名等,同时它也可以直接将数据写到响应流中
(2)视图
视图名的解析高度灵活,支持多种配置,包括通过文件扩展名、Accept内容头、bean、配置文件等的配置,甚至还可以自己实现一个视图解析器ViewResolver
(3)模型
模型(MVC中的M,model)其实是一个Map类型的接口,彻底地把数据从视图技术中抽象分离了出来。可以与基于模板的渲染技术直接整合,如JSP、Velocity和Freemarker等,或者还可以直接生成XML、JSON、Atom以及其他多种类型的内容。Map模型会简单地被转换成合适的格式,比如JSP的请求属性(attribute),一个Velocity模板的模型等
“对扩展开放”是Spring Web MVC框架一个重要的设计原则,而对于Spring的整个完整框架来说,其设计原则则是“对扩展开放,对修改闭合”
Spring Web MVC核心类库中的一些方法被定义为final方法。作为开发人员,不能覆写这些方法以定制其行为。当然,不是说绝对不行,但请记住这条原则,绝大多数情况下不是好的实践。
Spring模型-视图-控制器(MVC)框架是围绕一个DispatcherServlet来设计的,这个Servlet会把请求分发给各个处理器,并支持可配置的处理器映射、视图渲染、本地化、时区与主题渲染等,甚至还能支持文件上传。
处理器是应用中注解了@Controller和@RequestMapping的类和方法,Spring为处理器方法提供了极其多样灵活的配置。
Spring 3.0以后提供了@Controller注解机制、@PathVariable注解以及一些其他的特性,可以使用它们来进行RESTful Web站点和应用的开发
在Spring Web MVC中,可以使用任何对象来作为命令对象或表单返回对象,而无须实现一个框架相关的接口或基类。Spring的数据绑定非常灵活
比如:它会把数据类型不匹配当成可由应用自行处理的运行时验证错误,而非系统错误。可能会为了避免非法的类型转换在表单对象中使用字符串来存储数据,但无类型的字符串无法描述业务数据的真正含义,并且还需要把它们转换成对应的业务对象类型。有了Spring的验证机制,意味着再也不需这么做了,并且直接将业务对象绑定到表单对象上通常是更好的选择;Spring的视图解析也是设计得异常灵活。
新特性
Spring Web Flow (SWF) 意在成为Web应用中的页面流(page flow)管理中最好的解决方案
SWF在Servlet环境和Portlet环境下集成了现有的框架,如Spring MVC和JSF等。如果业务流程有一个贯穿始终的模型,而非单纯分立的请求,那么SWF可能是适合你的解决方案
Spring的web模块支持许多web相关的特性:
(1)清晰的职责分离
每个角色——控制器,验证器,命令对象,表单对象,模型对象,DispatcherServlet,处理器映射,视图解析器,等等许多——的工作,都可以由相应的对象来完成
(2)强大、直观的框架和应用bean的配置
这种配置能力包括能够从不同的上下文中进行简单的引用,比如在web控制器中引用业务对象、验证器等
(3)强大的适配能力、非侵入性和灵活性
Spring MVC支持你定义任意的控制器方法签名,在特定的场景下你还可以添加适合的注解(比如@RequestParam、@RequestHeader、@PathVariable等)
(4)可复用的业务代码,使你远离重复代码
可以使用已有的业务对象作为命令对象或表单对象,而不需让它们去继承一个框架提供的什么基类。
(5)可定制的数据绑定和验证
类型不匹配仅被认为是应用级别的验证错误,错误值、本地化日期、数字绑定等会被保存。你不需要再在表单对象使用全String字段,然后再手动将它们转换成业务对象。
(6)可定制的处理器映射和视图解析
处理器映射和视图解析策略从简单的基于URL配置,到精细专用的解析策略,Spring全都支持。在这一点上,Spring比一些依赖于特定技术的web框架要更加灵活。
(7)灵活的模型传递
Spring使用一个名称/值对的Map来做模型,这使得模型很容易集成、传递给任何类型的视图技术。
(8)可定制的本地化信息、时区和主题解析
支持用/不用Spring标签库的JSP技术,支持JSTL,支持无需额外配置的Velocity模板,等等。
(9)一个简单但功能强大的JSP标签库
通常称为Spring标签库,它提供了诸如数据绑定、主题支持等一些特性的支持。这些定制的标签为标记(markup)你的代码提供了最大程度的灵活性。关于标签库描述符(descriptor)的更多信息,请参考附录第42章 Spring JSP标签库
(10)一个Spring 2.0开始引入的JSP表单标签库
它让你在JSP页面中编写表单简单许多。关于标签库描述符(descriptor)的更多信息,请参考附录 第43章 Spring表单的JSP标签库。
(11)新增生命周期仅绑定到当前HTTP请求或HTTP会话的Bean类型
严格来说,这不是Spring MVC自身的特性,而是Spring MVC使用的上下文容器。
WebApplicationContext所提供的特性。这些bean的scope在6.5.4 请求、会话及全局会话scope一节有详细描述
允许其他MVC实现
有些项目可能更倾向于使用非Spring的MVC框架。 许多团队希望仍然使用现有的技术栈,比如JSF等,这样他们掌握的技能和工具依然能发挥作用。
如果确实不想使用Spring的Web MVC,但又希望能从Spring提供的一些解决方案中受益,那么将所使用的框架和Spring进行集成也很容易。只需要在ContextLoaderListener中启动一个Spring的根应用上下文(root application context),然后就可以在任何action对象中通过其ServletContext属性(或通过Spring对应的helper方法)取得。不需要任何侵入性的插件,因此不需要复杂的集成。从应用层的视角来看,只是将Spring当成依赖库使用,并且将它的根应用上下文实例作为应用进入点。
即使不用Spring的Web MVC框架,配置的其他Spring的bean和服务也都能很方便地取得。在这种场景下,Spring与其他web框架的使用不冲突。Spring只是在许多问题上提出了其他纯Web MVC框架未曾提出过的解决方案
比如:bean的配置、数据存取、事务处理等。因此,如果只是想使用Spring的一部分特性来增强应用,比如Spring提供的JDBC/Hibernate事务抽象等,那么可以将Spring作为一个中间层和/或数据存取层来使用。
MVC优缺点
优点(松耦合、高重用性、高可适用性)
(1)多视图共享一个模型,提高代码可重用型
(2)MVC三个模块相互独立,松耦合架构
(3)控制器提高了应用程序的灵活性和可配置性
(4)有利于软件工程化管理
缺点
(1)原理复杂
(2)增加了系统结构和实现的复杂性
(3)视图对模型数据的低效率访问
对于MVC来说它不适合小型甚至中型规模的项目,花费大量时间将MVC应用到规模并不是很大的应用程序通常得不偿失
Spring MVC框架特点
(1)清晰的角色划分
Spring MVC在Model、View和Controller方面提供了一个非常清晰的角色划分,这三个方面真正是各司其职、各自负责
(2)灵活的配置功能
因为Spring的核心是IoC,同样在实现MVC上,也可以吧各种类当作Bean来通过XML进行配置
(3)提供了大量的控制器接口和实现类
开发者可以使用Spring提供的控制器实现类,也可以自己实现控制器接口
(4)真正做到与View层的实现无关(JSP、Velocity、XSLT等)
Spring MVC它不会强制开发者使用哪种
(5)国际化支持
(6)面向接口编程
(7)Web应用开发的一整套流程
Spring提供了Web应用开发的一整套流程,不仅仅是MVC,它们之间可以很方便地结合一起。
为什么使用Spring MVC?(SpringMVC与Servlet的比较)
框架都是很复杂的,但是它们的优点(共同点)让使用者只关心核心业务的开发,框架屏蔽原有技术跟业务开发无关的各类技术问题。
Spring MVC技术的源头Servlet
Servlet的作用就是是接收浏览器传给服务端的请求(request),并将服务端处理完的响应(response)返回给用户的浏览器,浏览器和服务端之间通过http协议进行沟通,其过程是浏览器根据用户的选择将相关信息按http协议报文的规范组装请求的http报文,报文通过网络传输到指定的服务器,服务器通过特定的web容器接收这个报文信息。
例如:tomcat,jetty,jboss这样的web容器,web容器会将http报文解析出来,如果是用户请求,最终解析出来的报文信息会用一个request对象存储起来,服务端使用这个request做完相应的处理后,服务端程序将结果信息封装到response对象里,然后将response对象交给web容器,web容器则把这个response对象转变为http协议的报文,并将报文回传给浏览器,浏览器最后解析这个响应报文,将最终结果展示给用户。
而Web容器创造了Servlet接口,Servlet接口就是开发人员自己实现业务逻辑的地方,程序员开发Servlet就好比做填空题,而填空题的语境或者说上下文提示就是由request和response对象,但是javaEE规范里的servlet接口很简单,就三个方法init,service和destory,但是这个接口太笼统了,所以规范里还提供了一个HttpServlet类,这个类根据http请求类型提供了doGet,doPost等方法,servlet接口最大的特点就是根据http协议的特点进行定义,因此做servlet开发时候如果使用者对http协议特点不是特别熟悉,都会碰到或多或少令人迷惑的问题。
Servlet缺点:
就是请求的数据的类型转化,http协议传输都是文本形式,到了web容器解析后也是文本类型,如果碰到货币,数字,日期这样的类型需要根据实际情况进行转化,如果页面传送的信息非常多,就不得不做大量类型转化,这种工作没有什么技术含量,是个体力活而且很容易导致程序错误
Servlet另一个作用就是构造response对象,让页面获得正确的响应,其实现代的浏览器是一个多媒体工具,文字,图片,视屏等等东西都可以在浏览器里显示,资源的不同就会导致http响应报文的差别,如果我们使用servlet开发就要根据资源的不同在java程序里用硬编码的形式处理,这样的程序很难复用,而且如果程序员对某种资源的处理理解不到位,就会导致问题的出现。
Spring MVC
控制器Controller负责处理由DispatcherServlet分发的请求,它把用户请求的数据经过业务处理层处理之后封装成一个Model,然后再把该Model返回给对应的View进行展示。
(1)标记控制器(Controller)
在Spring MVC 中提供了一个非常简便的定义Controller的方法,无需继承特定的类或实现特定的接口,只需使用@Controller标记一个类是Controller
(2)定义URL请求和Controller 方法之间的映射(@RequestMapping)
使用@RequestMapping(配置在类或者方法上,它的作用是指定URI和哪个类或者方法作为一个处理请求的处理器)和@RequestParam(Spring MVC就知道从Http请求中获取参数)等一些注解用以定义URL请求和Controller 方法之间的映射,这样的Controller 就能被外界访问到。此外Controller不会直接依赖于HttpServletRequest 和HttpServletResponse 等HttpServlet对象,它们可以通过Controller的方法参数灵活的获取到。
Spring解决了什么问题?
控制反转的意思就是本来属于Java程序里构建对象的功能交由容器接管,依赖注入就是当程序要使用某个对象时候,容器会把它注入到程序里,这就叫做依赖注入。
在Java开发里想使用某个类提供的功能,有两种方式:
(1)构造一个新的类,新的类继承该类
(2)将某个类定义在新类里,那么两个类之间就建立一种关联关系
Spring IOC
Spring的IoC容器就是实现了这种关联关系(不是继承关系),那么某个类要被赋予到新类有哪些办法了?(IoC注入)两种标准的注入方式。
(1)通过构造函数
接口注入 constructor-arg元素用于定义类构造方法的参数,其中index用于定义参数的位置,而value则是设置值。
(2)通过属性注入(setXXX)
setter注入setter注入是Spring中最主流的注入方式,配置方式如下: property name与pojo一一对应,value为设置的值。
Spring很像银行,它不能直接创造物质财富,但是一切资源都要通过它进行流通,它能控制经济发展的走向,回到程序的世界,Spring的作用是被标榜为程序之间的解耦,Spring能降低不同模块之间的耦合度,原因就是在程序开发里不同模块之间信息的沟通是通过对象传递完成的,而对象能否顺利传递就是要合理的构建好对象,而管理好对象的构建方式就能管理好对象传递,这就是Spring给系统架构设计带来的好处