作者:熊节 / 插画:虎头锤

以 Spring 为代表的轻量级 J2EE 架构方案,不仅是一种技术方案,并且内蕴了与敏捷方法一脉共通的价值观。轻量级 J2EE 与 EJB 的技术方案之争,背后是瀑布与敏捷的方法之争。轻量级方案的流行,为后来敏捷的传播打下了群众基础。

从 EJB 到 Hibernate

“其实我以前也用 EJB 的呀,”范凯的嗓门有一种穿透性,一下子就把全桌人的注意力吸引过来,“前两年我做过一个规模很大的项目,当时就是用 EJB,在那个项目过程当中发现 EJB 有很多问题,然后才开始找别的替代方案。”

“就找到了 Hibernate?”庄表伟问道。虽说都在上海,JavaEye 这一群网友此前还没在线下聚过,这次是借着《程序员》杂志几位编辑来上海出差,顺道拜访当地作者,才聚在一起吃了一顿饭。庄表伟跟范凯在论坛上时有交流,真人还是第一次见。

“没有呢,那会儿大概是 2002 年吧,Hibernate 还没发布,我都想过自己做一个轻量级的框架来替代 EJB。后来到 2002 年底的时候就知道了有 Hibernate,那时候刚发布,很多地方不成熟,但是方向一看就知道是对的。所以我就开始研究,后来做项目也用,也推荐别人用。”

“对对,我记得你在彭晨阳的论坛上也推荐过 Hibernate,跟他还吵起来了。”

“可不是嘛,”范凯感叹道,“那段时间我发现呀,有很多人完全是不认可开源软件的,他们觉得必须要按照大公司的技术方案做架构才靠谱,你拿个什么二十几岁的年轻程序员做的开源框架出来推荐呀,他们觉得你不靠谱,你宣传的这都是些什么异端邪说。”

“其实要说软件的能力和架构的水平,还真不见得谁优谁劣。”

“对,不见得,而且这些人对开源方案多半是不熟悉的,不像我呀,我对 EJB 很熟,所以我是真的对比过优劣取舍。他们的论点经常就是说你这是个开源框架,所以就不靠谱。是不是开源框架就不靠谱、大厂商的方案就靠谱,我看也不一定。”

“我觉得很多人也不是真的要维护 EJB,只是要一种确定性。”庄表伟沉思一会儿说道,“有一套完整的架构方案,就可以照着做了,哪怕里面有坑,也是别人趟过的,自己没有风险。如果放弃了 EJB 用一套开源框架,可能就要遇到很多未知的坑。没有了确定性,很多人会感到不安全吧。”

“当然,也能理解,”范凯说道,“不过我相信,轻量级架构这套方案也会逐渐成熟,你看现在有 Hibernate、有 Spring、有 WebWork,用这些框架开发真的比 EJB 要轻松得多。越来越多的人会转到这上面来贡献和积累,完整的架构方案很快就会有。”

Java 技术栈的变迁是如何深受敏捷影响的?-编程知识网

复杂 + 开发效率低下:敏捷先驱们对 EJB 的嫌弃

彭晨阳一直认为,EJB(包括 Entity Bean)的能力是没有问题的。他甚至遵循 J2EE 推荐架构重新搭建了解道论坛,使用了 Session Bean 和 Entity Bean,试图“从实践角度来证明成熟技术的合理使用是多么重要”。

然而以 Hibernate 为代表的一批开源 Java 框架的支持者对构建在 EJB 基础上的“经典” J2EE 架构提出的挑战,重点很大程度上不在功能的完备。开源先锋们对 EJB 的批评,首先是过度复杂,然后是开发效率低下。

EJB 的设计初衷是要支持基于远程过程调用(Remote Procedure Call,RPC)的分布式应用架构,即把另一个进程(很可能位于另一台机器上)当做一个普通对象,像使用普通的 Java 方法一样发起跨进程乃至跨网络的方法调用。

为了达成这一目的,J2EE 应用服务器、尤其是 EJB 容器需要提供大量复杂的基础设施支持,也因而极大地增加了使用 EJB 技术开发应用程序的复杂度

一般而言,每个 EJB 组件至少需要 3 个 Java 类:业务接口、业务实现、RMI 骨架(skeleton),以及若干 XML 配置文件。即便应用服务器厂商提供了预编译工具帮助生成部分代码,使用 EJB 开发应用的复杂度仍然远高于使用 POJO(Plain Old Java Object,普通 Java 对象)。

EJB 这种复杂度使大厂商能够顺理成章地把应用服务器软件卖出高价,因此厂商的态度很明确:EJB 的复杂度是应对企业应用的复杂度所必需的。时任深圳金蝶中间件有限公司技术总监的袁红岗声称“如果项目中没有使用 EJB,就不能算是真正使用了 J2EE 技术”,表达的就是这样一种态度。

然而敏捷的技术领袖们对此并不买账。Martin Fowler 提出的“分布式对象设计第一法则”就是“不要分布你的对象”。以他为代表的一批技术领袖推荐的架构思路是在一个 Java 进程里完成所有业务逻辑, 用集群解决单台服务器负载过重的问题。这种架构风格实际上就把 Web 应用简化成了一个单进程编程的问题:不是“使远程调用变得透明”,而是根本没有远程调用。这样一来,是否必须使用 EJB(并承受其带来的复杂度),就不再像袁红岗所宣称的那样毋庸置疑了。

Java 技术栈的变迁是如何深受敏捷影响的?-编程知识网

倡导敏捷的技术领袖们拒绝 EJB 带来的复杂度,关键原因是这种复杂度造成了开发效率的损失。尽管应用服务器厂商努力通过代码生成和预编译手段减少业务逻辑之外的代码编写量,但这些措施又拖慢了修改代码之后看到反馈的节奏:对业务逻辑的每次修改必须经历漫长的“预编译—编译—打包—部署”过程才能生效,这个过程会耗费短则数十秒、长则数分钟的时间,这个时间间隔看似微小,却会每天无数次打击程序员频繁执行测试的积极性,从而对测试驱动开发等强调“小步前进”的开发方法造成致命的打击。

而这种对开发过程中频繁响应能力的诉求,采用瀑布式开发方法的团队没有强烈的诉求。支持与反对 EJB 的两群人彼此都会感到对方难以沟通,开发方法的差异是重要的原因之一。

以 Gavin King 为代表的一批年轻的企业应用架构师在他们职业生涯的早期就深受 Kent Beck、“Bob 大叔”、Martin Fowler 等敏捷先驱的影响,极限编程于他们而言是习以为常的工作方式。基于敏捷的习惯,他们提出了对 Entity Bean、继而对整个 EJB 体系的批评,不仅针对其能力、更针对其对快速反馈的影响。

并且,他们表现出了极强的技术主动性:没有等待大厂商主导的 J2EE 规范委员会回应,他们开发出了像 Hibernate 这样的替代框架,并以开放源码的形式将其发布给全行业使用。

时至 2004 年左右,敏捷与开源这两股细流汇集,形成了全面反对 EJB 的风潮,站在交汇处的也是一位深受极限编程熏陶的年轻架构师:Rod Johnson,他开发的开源框架有一个好听的名字,叫做 Spring

Java 技术栈的变迁是如何深受敏捷影响的?-编程知识网

Spring:敏捷的轻量级 J2EE 方案

正式指出“所有 J2EE 应用都应该使用 EJB”这种说法其实是个迷思(myth),Rod Johnson 可能是第一人。

他用大量实践经验雄辩地指出,滥用 EJB 很可能“导致代价高昂的错误”,而所谓“不滥用”,在 Johnson 看来,只有 EJB 的很小一个子集(即无状态 Session Bean)是值得使用的,其他部分都应该打上问号,使用无状态 Session Bean 的理由也只是提供远程方法调用(RMI)的一层封装;然而转过头来,他马上又提出,即使需要给其他应用程序提供服务接口,这种接口也可以用 HTTP 协议上的 Web 服务(例如当时流行的 SOAP 和后来流行的 REST)来实现,因此也不一定需要 EJB。

为了让这个“没有 EJB”的架构在企业应用环境中切实可行,他提出了轻量级容器架构:用轻量级(即基于 POJO 的)容器管理业务对象,通过容器提供声明式事务等基础设施能力,从而“享用 EJB……结构上的优势,又不受困于 EJB 的缺陷”。

Johnson 认为,这种架构的缺点只有三点

  • 第一,它不能直接支持 RMI 远程客户端,但正如他之前所说,他首先就认为 RMI 并不必要;
  • 第二,与 EJB 技术规范相比,目前轻量级容器还没有标准,但同时 POJO 对象本身就没有标准化的需求;
  • 第三,与 EJB 架构相比,这种架构对于开发者来说还有点陌生。

说得更直白一点,Johnson 认为轻量级容器架构全面优于 EJB 架构,J2EE 应用开发已经不需要 EJB。并且,他开发了名为 Spring 的轻量级容器,实现了自己阐述的架构。

当时国内有一大批年轻的一线技术人员正在积极地寻找 J2EE 企业应用架构和研发管理的实操指南,Spring 则提供了符合他们期待的答案:这个框架不仅提供了企业应用开发所需的数据库访问、事务管理等基础设施能力,还从工程结构、测试管理、甚至代码风格等方面提供了具体且可落地的参考。

Rod Johnson 对极限编程的偏好,以框架设计的形式具象化。例如 Spring 框架专门针对持久层、业务逻辑层和 Web 层分别设计了单元测试脚手架,鼓励对各层组件开展测试驱动开发。这种对于一线工程实践的重视,在 EJB、乃至此前的任何应用框架中都是没有的。

基于 Spring 提供的参考,一个对 J2EE 经验并不丰富的架构师可以在很短时间内建立起企业应用开发的基本结构与工作办法,这是 Spring 在国内迅速积累了一批拥趸的原因。

从 2003 年 9 月建站开始,就有这样一批与范凯经历相似的一线技术人员加入了 “Hibernate 中文站”的讨论。

这群人围绕 Spring 展开了大量高水平的讨论,例如杨戈(ID:Younger)和陶文(ID:taowen)翻译的《Spring 框架简介》,在很短时间内积累了超过 5 万次浏览,并被很多网站转载。这些高质量内容的聚集,使范凯的网站很快成为了华东地区一个小有知名度的技术论坛。

同时,这些讨论也把论坛的主题方向由 Hibernate 带向更为广泛的 J2EE 架构、技术与开发方法,这也是 2004 年初范凯将网站改名为 JavaEye 的原因。

随后的一段时间,JavaEye 论坛的一些高质量的内容在整个 J2EE 社区都有较大的影响,例如钱安川(ID:moxie)在业余时间编写的 WebWork 教程在 JavaEye 有超过 11 万次浏览,作为国内第一份针对 WebWork 框架的学习材料,被很多一线技术人员竞相传阅。

不过,在相当长的一段时间里,JavaEye 的名声仍然局限于一个较小的范围。这个发源于上海的技术社区在全国、全行业获得一定的知名度,并把 Spring 为代表的轻量级 J2EE 架构风格与敏捷的开发方法推向更广的范围,契机是 2005 年 Martin Fowler 的访华之行。

以上内容摘自《中国敏捷史》。

Java 技术栈的变迁是如何深受敏捷影响的?-编程知识网 Java 技术栈的变迁是如何深受敏捷影响的?-编程知识网

作者简介

作者:熊节,现任宝尊电商成都研发中心总经理,曾任 ThoughtWorks 总监咨询师、 CSDN 技术主编。

IT 行业打拼 18 年,在金融、零售、政府、电信、制造业、全球医疗等行业的信息化建设方面有着丰富经验。翻译了《重构》《软件工艺》《实现模式》等行业重要著作,是中国 IT 浪潮中敏捷发展的领航者之一。熊节拥有利物浦大学 MBA 学位。

插图:虎头锤,旅居墨尔本的老程序员,北邮博士、北大硕士,15 年编程经验。目前从事支付系统相关业务,曾转战区块链、通信行业。敏捷倡导者、手绘爱好者。