为什么会有Spring MVC
让我们追根溯源,从Web的发展讲起吧。
早期,Web开发还比较简单,开发者经常会去操作web服务器,并且他会写一些HTML页面放到服务器指定的文件夹(/www)下。用户使用浏览器输入对应的URL地址,访问到服务器上具体的html文件,服务器将具体的内容返回给浏览器,浏览器将html解析成视图的形式展示出来。浏览器中显示的网页仅是静态的图文组合而已,浏览者可以在网页上阅读信息,但无法进一步地发表意见、查询信息或进行在线购物等商务活动。从这里可以看出开发人员不仅仅要处理业务逻辑和页面展示,还需要完成网络部分的编写。
过了一段时间,人们发现静态网页远远不能满足大家的要求,用户需要跟服务端进行更好地交互。最简单的需求就是用户提交不同的信息,如用户名和密码,能够根据不同的用户返回与之对应的信息。首先是CGI的出现缓解了一点问题,制作一个简单的交互页面,却需要写大量的C代码,再之后微软强势推出ASP搭配IIS服务器,既解决了网络模块的编写问题,又解决了复杂性的问题,并且提供了访问数据库的接口,使得与数据库间的交互容易了很多。貌似解决了好多问题。后期又出现了PHP跟ASP也类似。这时候这两种语言都大行其道,其中最出名的应该是LAMP(Linux、Apache、MySql、PHP),深受中小型企业喜爱。
JAVA作为这个时期最流行的语言,自然要在Web领域分一杯羹,此时Java Server Page(JSP)应运而生,此时的Java Web应用整个都是由JSP页面组成的,JSP页面接收处理客户端请求,对请求处理后直接做响应。用少量的Java Bean与数据库进行交互。也就是说JSP充当了展示和请求处理的工作。
大家想想看这样会带来什么问题?没错,这样子的话,代码的重用性就会很低了,因为控制逻辑跟表现逻辑混杂在一起,Web开发者不仅仅逻辑要写对,而且展示的部分也要调试,这个过程非常地痛苦。确实正是由于这个原因,JSP没多少人用,它的本质跟ASP、PHP没多大区别。
标准做出来了却没有多少人用,他们自然不会善罢甘休,马上就想到了,业务逻辑跟展示逻辑不应该混合在一起,应该将其分开,接下来Java Web正式进入Model 2的时代,由Servlet来接收客户端发送过来的请求,Servlet中只包含控制逻辑和简单的前端处理;控制逻辑部分交给Java Bean来完成,其实这也是很有道理的,毕竟前期Java Bean只用来跟数据库进行简单的交互,交互完之后又传给JSP进一步处理,为啥不让Java Bean直接进行逻辑处理呢。Java Bean完成了复杂的逻辑处理之后,最后将结果给JSP进行展示。这时候分工很明确了,JSP只负责显示逻辑的部分。这就是非常经典的Java Bean+JSP+Servlet(MVC),这也就是著名的MVC设计模式。由于Model 2 引入了MVC模式,实现了组件化的管理,因此也具有了更好地扩展性。
大家觉得这么设计是复杂了还是简单了呢?
毫无疑问,当然是变麻烦了,本来实现一个HelloWorld,你只需要写一个JSP文件,结果现在却要写JSP和Servlet了,前期的开发成本自然是增加了,但是后期的维护成本却降低了不少,Model2就是为了降低系统后期维护的复杂度应运而生的。
可能有些同学还不太清楚,MVC每个部分是干嘛的,这里我啰嗦点我再重复一下,毕竟我们今天的题目是Spring MVC。
Model负责处理业务逻辑并且与数据库进行交互,以及通知视图更新数据;
View负责展示数据;
Controller负责请求处理,并调用Model的方法,然后选择相应的视图进行相应的展示;
整合在一起说,就是在Model2架构中,Servlet作为前端控制器,负责接收客户端发送的请求,在Servlet中只包含控制器逻辑和简单的前端处理;然后,调用后端JavaBean来完成实际的逻辑处理;最后,转发到相应的JSP页面处理显示逻辑。
这种开发套路让Java在Web领域生机勃勃,然后又到了2001年Struts框架诞生,由于其易用性,以及有丰富的标签支持并且能与Spring和Hibernate整合大大提高了开发效率,所以迅速成为了Web开发领域中的霸者。但是由于Struts1的线程安全问题、单元测试困难以及其对Servlet的依赖性太大等原因,后来又出现了Struts2,但是Strust2跟Spring结合存在多种问题,毕竟他们本来就不是一家人嘛,近年来Struts2还存在漏洞问题,所以用的人也越来越少了。此时Spring MVC渐渐走入开发者的视线中,成为了最广泛的Java EE开发框架。
我们回顾历史就回顾到这里吧。知道了Spring MVC的由来,现在我们想想就目前的这种JSP + Servlet + Java Bean这种开发套路有没有什么可以改进的地方。这里可能会有点难理解,不过我们需要大概了解它的设计过程,知其然还得知其所以然,接下来我们尝试一下能不能设计一个架构。