Spring深度探险1
Spring深度探险一声明:本文来自于:http://downpour.iteye.com/blog/1330537在我们熟知的建立在三层结构(表
Spring深度探险一
声明:本文来自于:http://downpour.iteye.com/blog/1330537
在我们熟知的建立在三层结构(表示层、业务逻辑层、持久层)基础之上的J2EE应用程序开发之中,表示层的解决方案最多。因为在表示层自身的知识触角很多,需要解决的问题也不少,这也就难免造成与之对应的解决方案层出不穷。
笔者在很多讨论中经常可以看到类似“某某框架已死”,或者“某某框架已经足以打败所有其他的框架”的言论。事实上,每一种解决方案都有着自身独有的存在价值和历史背景。如果单单从某一个方面或者某几个方面去看一个框架,那么评论难免有失偏颇。
所以,整个系列的第一篇文章,我们脱开SpringMVC框架本身,把SpringMVC放到一个更大的知识体系范围之中,讲一讲整个Web开发领域、尤其是MVC框架的发展历程。正如“认识历史才能看清未来”,当我们能够正确审视整个MVC框架的发展历程,也就能够分析它的发展趋势,并且站在一个更高的高度来对所有的解决方案进行评价。
两种模型
从整个B/S程序的运行结构来看,J2EE的表示层解决方案实际上是对“请求-响应”模式的一种实现。既然谓之“请求-响应”也就势必存在着两大沟通角色:

由于这两大角色的承载载体和编程语言实现基础都不同,因而也就产生了两种截然不同的针对表示层的解决方案的设计思路:
以服务器端应用程序为主导来进行框架设计以浏览器页面组件(及其自身的事件触发模型)为主导来进行框架设计
业界对于上述这两种不同的设计模型也赋予了不同的名词定义:前一种被称之为MVC模型;后一种则被称之为组件模型,也有称之为事件模型。
注:笔者个人对于这两种模型的概念定义并不是非常认同。因为在笔者个人的观点认为,MVC模型的定义角度所针对的是编程元素的划分;而组件模型(事件模型)的定义角度是动态交互方式的表述。所以我们在这里强调的是解决方案自身所设立的基准和侧重点的不同。
从使用者的社区力量上来看,无疑MVC模型获得了更多程序员的青睐。这里面的原因很多,我们在这里也不想过多展开对两种不同编程模型之间的讨论。不过在这里,我们将针对同一个业务场景(用户注册)分别给出基于这两个编程模型的代码示例,帮助读者了解这两种编程模型在设计思想上的不同之处。
【MVC模型】
在MVC模型中,我们选取当前比较热门的两大框架Struts2和SpringMVC作为代码示例。
首先,我们将用户注册场景中最为核心的“用户类”定义出来:
我们可以看到,Servlet的基本接口定义中:
参数列表 —— Http请求被封装为一个HttpServletRequest对象(或者ServletRequest对象),而Http响应封装为一个HttpServletResponse对象(或者ServletResponse对象)
返回值 —— 方法不存在返回值(返回值为void)
在这个设计中,HttpServletRequest和HttpServletResponse承担了完整的处理Http请求的任务。而这两个Servlet对象的职责也有所分工:
HttpServletRequest对象 —— 主要用于处理整个Http生命周期中的数据。
HttpServletResponse对象 —— 主要用于处理Http的响应结果。
这里实际上有一点“数据与行为分离”的意味。也就是说,在Servlet处理请求的过程中,其实也是Servlet中响应方法内部的逻辑执行过程中,如果需要处理请求数据或者返回数据,那么我们需要和HttpServletRequest打交道;如果需要处理执行完毕之后的响应结果,那么我们需要和HttpServletResponse打交道。
这样的设计方式,是一种骨架式的设计方式。因为Servlet是我们进行Web开发中最底层的标准,所以我们可以看到接口设计中的返回值对于一个最底层标准而言毫无意义。因为不存在一个更底层的处理程序会对返回值进行进一步的处理,我们不得不在Servlet的过程中自行处理浏览器的行为控制。
MVC模型的这一种形态,被笔者冠以一个名称:参数-参数(Param-Param)实现模式。因为在响应方法中,数据与行为的操作载体都以参数的形式出现。
Servlet的设计模型是所有MVC模型表现形态中最为基础也是最为底层的一种模型,所有其他模型都是建立在这一模型的基础之上扩展而来。
【Struts1.X】
Struts1.X是一个较为早期的MVC框架实现,它的历史最早可以追溯到2000年,作为Apache开源组织的一个重要项目,取名为“Struts”,有“基础构建”的含义。在那个程序框架尚处于朦胧阶段的年代,“基础构建”无疑是每个程序员梦寐以求的东西。
对于Struts1.X,我们还是把关注的重点放在Struts中的Controller层的定义上:
从图中,我们可以看到三类完全不同的发展方向。目前,Struts1.X这一条路被证明已经穷途末路;另外的两条发展轨迹总体来说实力相当,SpringMVC大有赶超之势。
那么,为什么曾经一度占领了大部分市场的Struts2会在近一段时间内被SpringMVC大幅赶超呢?这里面的原因多种多样,有自身架构上的原因,有设计理念上的原因,但是笔者认为,其本质原因还是在于Struts2对于技术革新的力度远不及SpringMVC。
如果我们回顾一下Struts2过去能够独占鳌头的原因就可以发现,Struts2的领先在于编程模型上的领先。其引入的POJO模型几乎是一个杀手级的武器。而基于这一模型上的拦截器、OGNL等技术的支持使得其他的编程模型在短时间很难超越它。
但是随着时代的发展,Struts2在技术革新上的作为似乎步子就迈得比较小。我们可以看到,在JDK1.5普及之后,Annotation作为一种新兴的Java语法,逐渐被大家熟知和应用。这一点上SpringMVC紧跟了时代的潮流,直接用于请求-响应的映射。而Struts2却迟迟无法在单一配置源的问题上形成突破。当然,这只是技术革新上的一个简单的例子,其他的例子还有很多。
有关Struts2和SpringMVC的比较话题,我们在之后的讨论中还会有所涉及,不过笔者并不希望在这里引起框架之间的争斗。大家应该客观看待每个框架自身设计上的优秀之处和不足之处,从而形成个人自己的观点。
从整个MVC框架的发展轨迹来看,我们可以得出一个很重要的结论:
downpour 写道MVC框架的发展轨迹,始终是伴随着技术的革新(无论是编程模型的改变还是引入新的编程元素)共同向前发展。而每一次的技术革新,都会成为MVC框架发展过程中的里程碑。
小结
在本文中所讲的一些话题触角涉及到了Web开发的各个方面。作为SpringMVC的前传,笔者个人认为将整个MVC框架的发展历程讲清楚,大家才能更好地去了解SpringMVC本身。而我们在这里所谈到的一些概念性的话题,也算是对过去十年以来MVC框架的一个小结,希望对读者有所启示。