【转】关于Spring、Struts、Hibernate三大框架

作者:David链接:https://www.zhihu.com/question/21142149/answer/148286909来源:知乎著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

第一部分:基本概念
首先我们应该了解这三个框架分别是做什么的,在Java开发中具有什么样的作用,对于理清楚框架中具体的知识点是大有裨益的。

  1. Spring:DI/AOP
    Spring对应的关键词是DI(依赖注入)与AOP(面向切面编程),可以认为是一个以DI和AOP为核心Java Web一站式的集成(粘合)框架。
    其中DI也称为IoC(控制发转)用于管理Java对象之间的依赖关系(一定要说DI是IoC实现方式的童鞋们见评论区),AOP用于解耦业务代码和公共服务代码(如日志,安全,事务等)。DI和AOP能够让代码更加简单,具有良好的松耦合特性和可测试性,极大地简化开发。理解这两者是使用Spring框架的基础。
    Spring框架对Java企业应用开发中的各类通用问题都进行了良好的抽象,因此也能够把应用各个层次所涉及的特定的功能和开发框架(如接下来要说的MVC框架、ORM框架)方便得组合到一起(这也得益于依赖注入和面向切面编程带来的强大功能)。Spring是一个极其优秀的一站式的Full-Stack集成框架,因此基于Spring核心,对Java应用开发中的各类通用问题几乎都提供了针对性的开发框架,比如你耳熟能详(如果你对这个问题感兴趣的话)的Spring MVC,Spring Data。
    Java曾经有另外一个类似的一站式框架粘合框架Seam,这是Hibernate的作者、脾气火爆的大神Gavin King的作品,核心是基于依赖注入来黏合JSF和EJB,不过推出时Spring已经大杀四方,Seam基本已经退出历史舞台了。记得Seam提过一个我认为很不错的概念:“双向注入”,类似现在前端框架中的双向绑定,当时来说还是很超前的。
  2. Struts:MVC
    Struts是一个Java Web MVC开发框架。MVC早在1978年就作为Smalltalk的一种设计模式被提出来了,引用到Web应用中来时:模型Model用于封装与业务逻辑相关的数据和数据处理方法
    视图View是数据的HTML展现
    控制器Controller负责响应请求,协调Model和View

Model,View和Controller的分开,是一种典型的关注点分离的思想,不仅使得代码复用性和组织性更好,使得Web应用的配置性和灵活性更好。
MVC开发模式下,Java Web开发会遇到URL路由、模板渲染、表单绑定/提交/验证、Session封装、权限验证、国际化等一系列通用的问题,而MVC框架会将这些通用问题都封装进框架中,你在应用中根据自己的场景进行简单的配置和编码即可,MVC框架就能帮你处理好一切,可以极大地简化代码。
看到“MVC框架会帮你处理好一切”,不知你是否知道这句著名的话(印象中出自GoF?):不要调用我,我会调用你。再扯远一点,这其实是依赖注入(DI)/控制反转(IoC)概念的最初来源啊,去看看Martin Fowler的博客就知道了:)。
Struts曾经是最流行的Java Web MVC框架,现在常见的选择是Spring MVC。

  1. Hibernate:ORM
    Hibernate是一个Java ORM开发框架
    ORM是Object Relation Mapping的缩写,顾名思义,即对象关系映射。
    ORM是一种以面向对象的方式来进行数据库操作的技术。Web开发中常用的语言,都会有对应的ORM框架。而Hibernate就是Java开发中一种常用ORM框架,另一个现在流行的ORM框架是Mybatis
    为什么需要ORM框架?
    简单地理解,通过Java进行数据库访问的正常流程可以分为以下几步:准备好SQL语句
    调用JDBC的API传入SQL语句,设置参数
    解析JDBC返回的结果

这个过程实际上非常麻烦,比如:在Java代码中拼接SQL非常麻烦,而且易于出错
JDBC的代码调用有很多重复性的代码
从JDBC返回的结果转换成领域模型的Java对象很繁琐

而使用ORM框架,则可以让我们用面向对象的方式来操作数据库,比如通过一个简单的函数调用就完成上面整个流程,直接返回映射为Java对象的结果。这个流程中很大一部分工作其实可以交给ORM自动化地帮我们执行。对,类似MVC框架,ORM框架会帮你处理好相关的繁琐事情!
第二部分. 三个框架产生的技术历史背景
SSH是Java Web开发的技术框架,我们简单回顾一下Web应用的发展。
1991年Web页面在Internet上的首次登场,最早Web主要被一帮科学家们用来共享和传递信息,浏览器中主要展现的是静态的文本或图像信息。不过大家很快就不仅仅满足于访问放在Web服务器上的静态文件,1993年CGI(Common Gateway Interface)出现了,CGI定义了Web服务器与外部应用程序之间的通信接口标准,因此Web服务器可以通过CGI执行外部程序,让外部程序根据不同的Web请求生成动态内容。而在Java Web开发中的Servlet,其原理与CGI是类似的。
那个时候编写CGI程序的主要是Perl和C等语言,在程序中输出大片的HTML字符串,可读性和维护性是个大问题。为了处理更复杂的应用,一种方法是把HTML页面中固定的部分存起来(称之为模版),把动态部分打上标记,处理Web请求时,后端程序生成动态的内容然后填充进到模板中去,形成最终返回的HTML。于是1994年PHP诞生了,PHP可以把程序(动态内容)嵌入到HTML(模版)中,不仅能更好的组织Web应用的内容,而且执行效率比CGI还更高。之后96年出现的ASP和98年出现的JSP本质上也都可以看成是一种支持某种脚本语言编程(分别是VB和Java)的模版引擎。
Web开发脚本语言,搭配上后端数据库技术,Web开始大杀四方,类似电子商务系统这样的复杂应用也开始出现在互联网上。如第一部分所述,这时MVC的概念被引入到Web开发中来了。这时一个典型的Java Web应用从架构上看起来应该是这个样子:

【转】关于Spring、Struts、Hibernate三大框架_第1张图片

【转】关于Spring、Struts、Hibernate三大框架_第2张图片
Web浏览器发送HTTP请求到服务端,被Controller(Servlet)获取并进行处理(例如参数解析、请求转发)
Controller(Servlet)调用核心业务逻辑——Model部分
Model进行数据库存取操作,并将操作结果返回给Model
Controller(Servlet)将业务逻辑处理结果交给View(JSP),动态输出HTML内容
动态生成的HTML内容返回到浏览器显示

接下来就该MVC框架(以Spring MVC为例)和ORM粉墨登场了:


【转】关于Spring、Struts、Hibernate三大框架_第3张图片

【转】关于Spring、Struts、Hibernate三大框架_第4张图片

Spring MVC提供了一个DispacherServlet(可以Spring MVC是以Servlet技术为基础的),这个Servlet把Web应用中Servlet中经常要实现的功能封装起来并提供一层公共抽象,想象对应于一个Web请求后端要做的事情,比如:URL映射(对应HTTP URL和方法,应该调用什么代码)
权限验证(当前的URL是否允许当前用户访问)
参数解析(如何从Servlet中获得参数)
数据绑定(如何将Servlet中的参数,绑定到业务逻辑对象中)
数据验证(判断数据是否符合业务规则,比如邮件格式是否正确)
视图解析(使用哪个视图模板进行渲染)
模型传递与视图渲染(将数据传递给模板,并且在模板中引用)
...

有了Spring MVC,你只需写简单的POJO代码(如图所示,用POJO实现Controller),或者实现Spring MVC给你提供的接口(比如实现Interceptor做权限判断),就能完成这些繁琐的功能。

POJO是Plain Old Java Object的缩写,是软件开发大师Martin Fowler提出的一个概念,指的是一个普通Java类。也就说,你随便编写一个Java类,就可以称之为POJO。之所以要提出这样一个专门的术语,是为了与基于重量级开发框架的代码相区分,比如EJB,我们编写的类一般都要求符合特定编码规范,实现特定接口、继承特定基类,而POJO则可以说是百无禁忌,灵活方便。

而ORM的作用就非常直观了,无须赘述,如图所示它提供了与数据库操作的一层中间抽象,这样Model的代码自然会更加简单。Spring MVC基本可以帮你屏蔽Servlet的API,ORM则可以帮你屏蔽JDBC的API了,也就是说你在更高的抽象层次上写程序了,更高的抽象层次一般意味着以更符合我们思维的方式来思考,自然效率更高。这事实上是软件技术发展的一个重要驱动力之一。你想想,从汇编语言发展出高级语言,从文件系统发展出数据库,其实本质规律是类似的。

那Spring的作用是什么呢? 看到图中大量的箭头没有?

图中的每一个小方块其实都是大量的Java类来实现,Controller与Model之间,Model与数据访问对象之间的这些箭头,意味这些Java类之间存在大量复杂的依赖关系。Spring的核心功能依赖注入,正是用于管理Java对象之间的依赖关系,所以第一部分我们说Spring是一个一站式的粘合框架,它像神奇的胶水一样,可以以松耦合的方式有机的粘合在一起。那具体怎么做到的呢?后文分解。

回到历史,Web开始大杀四方之时,大型应用在分布式、安全性、事务性等方面的要求进一步催生了J2EE(现在已更名为Java EE)平台在1999年的诞生。但是J2EE的组件技术EJB(Enterprice Java Beans)非常笨重,Spring的初衷是为了替代EJB,让Java EE开发更加简单灵活。它起源于Rod Jahnson 2002年出版的著作《Expert One-on-One J2EE Design and Development》,那本书中分析了Java EE的开发效率和实际性能等方面的问题,从实践和架构的角度探讨了简化开发的原则和方法。以此为基础,他实现了一个名为interface21的轻量级开发框架,成为Spring框架的前身。2004年,Spring正式发布1.0版本,同年Rod Jahnson推出了另一部影响深远的经典著作《Expert one-on-one J2EE Development without EJB》,Spring开始逐步在Java领域流行。现在Spring框架的版本已经演化到了4.x,它已经成为Java开发框架的一种事实标准,对Java EE规范本身也产生了重要影响。比如EJB规范就在发展中逐渐引入了众多Spring框架的优秀特征。

好了,你现在应该可以从更高和更广的技术视野来看待这几个框架了吧。看到一门技术的发规律和发展历程,这是一种技术修养的体现,跟人文修养是类似。但是同时我们也应该具有一定的深度,因为我们往往已经站在比较高的抽象层次,比如今天你写几行代码就能把数据库创建好,增删改查的功能也自动生成好了,但是成为高手需要你对底层的原理机制有更透彻的理解,真正遇到问题的时候才能抽丝剥茧迎刃而解。所以要看第三部分:需要了解的基础知识。

你可能感兴趣的:(【转】关于Spring、Struts、Hibernate三大框架)