[转帖]知乎: JavaEE与Spring的关系

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

在回答题主的问题之前,我先要简单介绍一下什么是JavaEE,什么是Spring。

JavaEE是一组建立在JavaSE之上的标准,解决企业级开发中的一系列问题。请特别留意,它仅仅是个标准,是对一系列接口的约定,众多厂商围绕这个标准做实现。如JBoss,WebSphere等。第一个版本的JavaEE 1.2在1999年被发布,到2017年的JavaEE 8,已经经历了将近20年。

那么JavaEE都有哪些标准,解决了什么问题呢?我这里简单列举一下主要的标准:

  • Servlet:定义了如何处理Web请求,这个相信大家最熟悉
  • Java Server Faces:定义了如何使编写Web界面
  • JAX-RS:定义了如何编写RESTFul的接口
  • EJB:定义了如何编写“企业Bean”
  • JPA:定义了如何编写ORM和数据存取
  • JTA:定义了如何编写事务相关的代码
  • JMS:定义了如何编写消息队列程序
  • CDI:定义了如何编写依赖注入
  • JAX:定义了如何编写XML程序
  • JAX-WS: 定义了如何编写基于XML的网络服务,即SOAP
  • ……

看到这些,你可能机会发现,你平时其实经常使用其中一些标准接口,即便你认为你在用Spring。

什么是Spring呢?Spring最早可以追溯到2002~2004年。在那几年作者Rod Johnson出版了两本书:“Expert One-on-One J2EE Design and Development“和“Expert One-on-One J2EE Development without EJB“,和最初几个版本的Springframework。

早期的Spring定位于解决J2EE在实际使用上的一系列问题,因为JavaEE的API实在是太难用了。Rod估计是趟了不少大坑,于是总结了一套最佳实践,并总结到了一套框架里。其中最重要的,就是所谓IoC(控制反转)。

经过多年发展,Spring发布了很多组件:

  • spring-core:Spring的Bean的管理,控制反转和程序上下文
  • spring-mvc: web开发中的model-view-controller
  • spring-data: 数据层访问和封装
  • spring-boot: spring全家桶自助配置和部署管理工具
  • spring-batch:一个简单的批处理框架
  • spring-cloud:支持与许多云服务接口的整合
  • spring-security:认证和权限管理
  • ……

spring中其实大量使用或者实现了JavaEE标准。比如spring-mvc是在servlet基础之上的封装。spring本身并不提供容器,而是支持使用任何支持servlet标准的容器(如tomcat,jetty等)。spring-data也实现了JPA,通过标准接口对进行CRUD等。

归根到底Spring只是想更好的解决实际问题。JavaEE的实现做得好的就用,做得不好的用比较恰当的方式独立实现或者封装。俗称“接地气”。

见过不少人喜欢用“JavaEE vs Spring”来提问引战。但是,由上面的介绍可以看到JavaEE和Spring并不对立。作为开发工程师,其实还是哪个能解决问题,生态好,支持好,成本低就用哪个。而且混着用也没有什么大的问题。

随着时间的发展,JavaEE已经越来越落后,这是由于它的体制造成的。JavaEE的制定是由几大巨头定期开会协商通过,发布。然后个大容器实现厂商跟进。但这样太慢了。互联网的发展速度已经远不是这样一个僵化的体制能够适应的。反观Spring相对就快速的多。Spring自己就是一家公司,觉得整个社区什么东西最前沿,最急缺就立刻响应去做了。比如,Restful刚流行,你是愿意等一年半载出JAX-RS标准,然后再出Jersey,才能用;还是选择直接用Spring MVC直接就把事办了?结果不言而喻。对解决问题的态度是二者目前境遇不同的主要原因。

扫描二维码关注公众号,回复: 8676179 查看本文章

最早期JavaEE是领导者,所有的技术厂商要想在这个圈子里混,必须跟着标准走。而Spring逐渐占据领导地位之后,JavaEE的一些标准反而要跟着Spring走。CDI就是一个很好的例子。Spring IoC是整个框架的核心。它解决了在Java中只能import类,却import不了组件的问题。这个问题在js,python之类的环境中都是小菜一碟。但是Java中,如果没有IoC,程序员就要花大量的时间写new和set,组装整个服务的引用关系(你不觉得这很不人道吗?)。Spring流行之后,JavaEE在2009年才发布CDI标准。其样子就是活脱脱的把Spring的Annotation换了个名字而已。

如果说未来的发展,我认为JavaEE早已经没有了未来。JavaEE里那些做得很好的,或者和其他框架能够很容易相融的标准继续存在;那些被骂成翔的,比如JSF;或者一开始就没有市场的,比如CDI,会成为Wiki上的一段段文字记录。但,Spring也不一定好过。在Java体系内他也要面临play,vert.x的冲击;在体系外,它会受到其他语言环境的巨大压力,如nodejs,python和go。说Spring灵活是相对于JavaEE而言。

无论标准、框架、服务,都是为了解决问题而存在,而不是如“多么的OO”,“多么的标准”,“多么的概念清晰“。哪个工具解决的好,解决的快,就用哪个。最近2~3年,docker+微服务的发展进一步的强化了这个现实。大量的新技术会随着业务领域形成自己的生态。

这其实是好事,不是吗?


P.S. 题主在题目中给了一个文章,我认为其JavaEE和IoT的说法完全是扯淡。一个不注重解决问题,总想画个大饼的东东,还想抢占新领域?先老老实实做几个能跑的东西再说吧。

 


2018年3月17日更新。

有知友询问还是不理解什么是规范。那我索性再唠叨一些。

Java各种标准的制定是通过Java Community Process - JCP进行的。JCP的成员可以根据需要提出Java Specification Request - JSR。每个JSR都要经过提交给JCP,然后JCP讨论,修订,表决通过,并最终定稿;当然,运气不好的就被拒绝/废弃了。

而JavaEE是一组被通过的JSR的合集。JSR和JavaEE的关系就好像是文章和经过编辑整理过的文集。

以Servlet为例。Servlet的标准有很多个版本,从1.1到目前最新的4.0。Servlet从2.2版本被纳入到JavaEE。目前比较常见的Servlet 3.0是JSR-315,在2009年年底发布。在JCR Servlet 3.0可以看到这个提案整体的流程,并可下载原文。

那么到底什么是Specification呢?是一组实现约定。

还拿Servlet规范举例子,它的其中一个规定是:为了支持处理一个Web请求,必须实现一个HttpServlet类,这个类必须继承Servlet接口,当然也得实现其中的所有接口方法,比如doGet,doPost。doGet方法必须接受两个参数,HttpServletRequest req, HttpServletResponse resp,分别表示请求和返回,出了问题可以返回ServletException或者IOException。

整个规范大概几十上百页。所规定的项目包括接口定义,抽象类和关系,状态和生命周期等等。而所有开发基于Java的企业应用的厂商就可以选择支持这些规范。Tomcat、Jetty、glassfish等都支持Servlet。所以你不管用哪个,编写出来的Java代码是基本一样的。

当然,这些实现除了支持规范外都有各自独有功能和接口,不然咋竞争……。

但白话了这么多,我其实是希望大家不要过于在意JavaEE到底是什么这件事情。

在开发时,并不会以“一个库是不是遵守标准“为最优先的考量(尽管一些标准狂热分子的确会这样,还会时不时圣战一把)。如果有能干活的框架/库,符合一个广泛接受的标准,当然好;如果不符合,也不用太纠结。毕竟我们是为自己的工作任务打工,而不是为标准和编程语言打工,对吧?

猜你喜欢

转载自www.cnblogs.com/jinanxiaolaohu/p/12161175.html