Bert Ertman 专访:将 Spring 及遗留应用迁移到 Java EE 6 平台

阅读数:2106 2013 年 11 月 4 日

话题:语言 & 开发架构

本文来自于 2013 上海 JavaOne 大会上对 Luminis 公司 Bert Ertman 的专访。在这篇访谈中,Bert 谈到了从 Spring 及遗留应用迁移到 Java EE 6 平台的重要性与必要性。他详细剖析了 Java EE 6 平台的诸多新特性、Spring 应用可能存在的问题、应用迁移的场景与方式、如何通过 Java EE 6 的新特性来实现 Spring 框架的相应功能、如何根据实际的业务场景说服公司高层进行应用迁移、如何通过 Java EE 6 平台进行单元测试与集成测试等等。最后,Bert 又谈到了微部署的优势与价值以及 Web MVC 前移的发展趋势。本文对于从事 Java 企业开发、Java 应用服务器开发、Spring 应用开发的开发者、项目经理及架构师来说颇具价值,同时也详尽比对了 Spring 与 Java EE 6 平台的众多特性。

InfoQ:你好 Bert,很高兴能够采访你,请先简单介绍一下自己吧。

Bert:没问题。我叫 Bert Ertman,来自荷兰,目前在 Luminis 工作,这是荷兰的一家服务公司。我们提供咨询服务,主要使用 Java 技术帮助客户完成项目。此外,我们还做一些产品开发,同时进行大量的开源创新,并借此构建我们自己的产品。我从 Java 发布不久之后就开始使用 Java 了,因此非常幸运能在大学期间就在公司实习,并且见证了 Java 的首个公开 Beta 版,以及 Java Alpha 2,即 1.0.0.Alpha 2。早在 1995 年我就使用 Java 编写了一些 Applets,这些年来我主要就使用 Java 进行开发,与此同时我也亲眼目睹了 Java 的发展。在 1999 年左右,企业开发开始蓬勃发展。那时 Applets、Servlet、JSP 以及后面的 EJB 开始崭露锋芒,接下来 Java 2 企业版发布。在过去的 10 多年间,我开始使用这些技术为银行、保险公司、政府组织及警队构建企业应用。在这些年间,我使用了 J2EE、Spring 及 Java EE 等各种技术,可以这么说,我见证了一个时代的发展。

除了日常工作外,我还是 NLJUG Java 用户组(即荷兰 Java 用户组)的负责人,该组织拥有 3,500 名左右的成员。我们组织自己的活动,并且举办了名为“J-Fall”的会议,该会议一天就吸引了 1,200 个人参加。一般来说,这个会议会在每年 11 月的第一周召开。到目前为止,该会议已经举办了 10 届,非常成功。

从 2008 年开始,我还成为了 Java Champion,对此我感到非常荣幸。这就是我的简单介绍。此外,我还是 O'Reilly 即将出版的新书《Building Modular Cloud Apps with OSGi》的作者。

InfoQ:谢谢。众所周知,Spring 是 Java 领域最为流行的框架,很多开源或是闭源框架都会与之集成,那么我们为何还要从 Spring 迁移到 Java EE 6 上呢?迁移的好处与代价如何?

Bert:这是个非常好的问题。在演讲中我对这个问题做过解释,我首先就提到开发者不应该立马就开始着手进行迁移。从业务角度来说,如果有业务场景需要你这么做才是最为重要的。业务场景可能是你有一个 7、8 年前构建的应用。你使用 Spring 来构建应用,因为那时 Spring 是 Java 企业开发栈唯一正确的选择,J2EE 缺乏太多的特性了,所以 J2EE 叫做“Java 2 Evil Edition”看起来更合适,在那个年代,使用正确的选择来构建应用是天经地义的事情。不过时过境迁,当时的很多应用都在使用现在已经过时或是陈旧的映射技术来构建,比如说 Kodo 或是 Toplink,这些技术的发展已经有些停滞不前了,维护这些应用变得非常困难。如果老板对你说,这个已经运行了 8 年的应用还要再运行 5 到 10 年,同时还需要添加一些新功能,那么你将面对大量的技术债务。你首先要告诉老板的可能就是我们可以让应用再运行几年,不过需要进行重构。我们需要替换掉一些陈旧的技术,即便不迁移到 Java EE 而是坚持使用 Spring,那么升级工作也需要花费不少时间。为了更能适应未来的发展,我倾向于使用标准技术,因为标准的兼容性会持续很长时间。举个例子,如果你觉得没问题,那么我希望将 Kodo 替换为 JPA,因为 JPA 将会存在相当长的一段时间。

因此,从现在开始的 5 年内,你将不会再遇到现在使用 Kodo 时所遇到的那些问题。这是我要说的一个原因,但不管怎么说,我们面临的工作量还是不小的。不过,我还要多说几句,我不仅是要替换掉一两个组件,而是在业务场景允许的情况下将整个应用都迁移到标准上来,这样可以确保在未来几年的兼容性。我认为这对于迁移来说是个非常合适的业务场景。不过,这在很大程度上取决于你所在的公司是否有这样的业务场景。

Java EE 成为令我们所关注的选择还有另外一个原因,这正是我的演讲的另外一个效应,那就是太多的人、太多的开发者们在 J2EE 之后就没再了解过 Java EE。他们会说,J2EE 不行,因此会使用 Spring,他们从来也没了解过 Java EE。但是,在过去的 5、6 年间有太多的变化,Java EE 5,特别是 Java EE 6 已经成为当下的主流 EE 平台。我的意思是,7 也很好,不过它太年轻,还不能用在生产上面。支持它的应用服务器也不太多,顶多就那么一两个而已,或许一年之后就会有更多的应用服务器支持它了。不过,由于 Java EE 6 是主流技术,它真的太强大了,至少与 Spring 持平。特别是对新的开发来说,我鼓励大家——特别是那些不是 Spring 粉丝而只是使用这样一个企业栈的 Spring 开发者们——看看 Java EE 6 吧,你所需要的一切都在那里了。

依我来看,Java EE 对于新的开发来说也是个非常不错的开发栈。不过,适于迁移的业务场景尤其对于我所说的“保守派 Spring 应用”,甚至是遗留的 Spring 应用来说是适合的。如果在 3 个月前使用新的 Spring 框架来构建 Spring 应用,那么在这种情况下进行迁移就不太好了。新的 Spring 栈也对各种 Java EE 6 技术提供了内建的支持,比如说提供了对 JPA 的支持、对 Restful Web Services、JAX-RS、甚至是 JSF 的支持。你会看到,随着时间的流逝,Spring 框架也在不断向一些 Java EE 6 技术看齐。

InfoQ:照你这么说,他们二者之间在不断融合,而且彼此之间的兼容性越来越好?

Bert:是的,因为一些新的技术标准,如 JPA、JAX-RS 等确实是非常棒的标准,这些标准也有非常不错的实现。Spring 之所以会集成他们是因为他们确实棒,我觉得 Spring 就像是个大胶水盒子似的。它也是个集成框架。就好比你拿起这个,再拿起那个,然后在他们之间放点 Spring 胶水,这样就得到了一个 Spring 应用。不过事实上,下面的技术却是 Java EE 技术。Spring 也在慢慢地向这个方向转变。他们对于 CDI 有点犹豫,因为如果开始拥抱 CDI,那么 Spring 就没什么价值了。Spring 的核心就是依赖注入,如果有足够的控制,那么整个胶水场景就不复存在了,但这是另一个话题。

InfoQ:对于迁移代价来说,你有什么例证么?

Bert:代价其实是很难计算的,因为没有两个项目是一模一样的。不过,我提议逐步迁移的原因之一就是你无需一下子就把所有事情做完,因为如果一开始就要重构一切的话,那么最后只会一团糟。我提出的迁移途径是首先替换掉真正的技术债务,他们基本上是些过时的框架,如果由于业务的原因不能再往下走,那也没问题。你只需完成迁移的一两个步骤,替换掉一些痛苦点,这也不错。

这是个渐进的迁移过程,如果你有一个项目团队,时间是两个月,他们有自己的日程安排,你也必须要遵循这个安排,因此你不能说,我们花一年时间来迁移吧。如果有几周或几个月的时间来完成部分迁移,那么你就可以开始构建新功能了。接下来可以进行后续的迁移,构建新功能,再做点迁移,然后再构建新功能。这不是一蹴而就的事情,你可以按照适合自己的节奏来做。你不必走到老板面前说,我们要花一年的时间进行迁移,没法再构建任何新功能了。我的迁移过程的一部分就是同时运行 Spring 与 Java EE,这时很容易使用 Java EE 6 来创建新功能,同时应用的主要部分依旧使用 Spring。在同时使用 Spring 与 Java EE 时,我们会使用一些技巧通过 CDI 来查找 Spring Bean,这样他们就能用在 Java EE 6 中了,而通过 Spring 进行查找则是你不太想做的事情,因为你不打算在 Spring 上进行投资了。所有新功能都是基于 Java EE 标准的了。

因此,很难说一个典型的项目迁移的代价是多少。我在演讲中想要表达的是我希望人们能够考虑这一点,我想要告诉他们该如何去做。

InfoQ:我们是不是应该按照周或是月来做计划呢?

Bert:我觉得应该按照天或是周而不是月来做计划。如果按照月来计划迁移,那就意味着有很多个月无法构建新功能,没人会觉得这是个好主意。你应该小步前进,小步迭代。我的建议是从外向内进行。首先替换掉应用边缘处的痛苦之处,然后再逐步向应用核心递进。与此同时,开始使用新的 Java EE 技术来构建新功能,使之集成到现有的应用。

InfoQ:Spring 是个一站式 Java 框架,提供了典型的 Java 项目中所需的各种功能,如 Web MVC、事务管理、IoC、数据访问集成等等。最重要的是,它只需一个 Servlet 容器即可运行,比如说 Tomcat。既然有了现成的这些功能,我们迁移到 Java EE 6 仅仅因为 Spring 是个私有技术,而 EE 6 是标准么?毕竟,Spring 是个开源框架,我们可以获得其源代码。你对此是如何看待的?

Bert:我觉得这是两个问题。首先,也是我为何以二者之间的功能比较作为演讲开场白的原因所在,我被问了很多问题,提问的不少人最近都没有关注过 Java EE。他们说,我真的需要依赖注入;或是说,我需要 Spring 的这个特性,在使用 Java EE 时我不想牺牲他们,因此我做了这个对照表格。你在企业应用中需要很多功能,如依赖注入、事务、Web 框架、面向方面编程、消息、数据访问、Restful Web Services、集成测试等等,他们都是你所需的典型功能,看看 Spring 提供了哪些呢?

Spring 提供了全部,下面来看看 Java EE,看看 Java EE 对于这些技术提供了哪些替代方案。从表中可以看到的是 Java EE 技术至少与 Spring 所提供的持平,依我来看,Java EE 提供了更好的选择。就拿依赖注入来说,Java EE 并不仅仅实现了依赖注入,还提供了上下文依赖注入。你可以注入到一个作用域当中。比如说,你可以将一个 Bean 注入到请求或是会话当中,在请求或是会话结束时,该 Bean 就会脱离相应的作用域。

这确实非常强大,CDI 还有一个扩展机制,我在迁移过程中使用很多。对于事务、Web 等我方才提到的其他一切特性来说都是如此。现在的 Java EE 对于这些特性都提供了替代者。它只缺乏一样,即集成测试。这也是我总提到 Arquillian 测试框架的原因所在,它是由 JBoss 构建的开源框架,不过它并不限于 JBoss,你可以在任何应用服务器上使用它。现在,你也在 Java EE 中拥有了真正强大的集成测试。

我认为对于新的开发或是迁移过程,从主流栈来说,Java EE 至少提供了 Spring 所提供的一切,如果需要其他功能,你可以在此之上更进一步,特别是集成 CDI。比如说,有个名为“Apache deltaspike”的开源项目,它包含了大量的 CDI 扩展。我认为它实际上来自于之前的 Seam 项目。很多 Seam 组件都被纳入到了 deltaspike 中。

他们提供了可选组件来实现安全和大量额外的功能,这些功能可以轻松集成到 Java EE 中,因为 Java EE 只是个规范,有不同的厂商来实现它,比如说 JBoss、Oracle 及 IBM 等。他们在 Java EE 之上提供了一整套功能。在演讲后,有人问我,他需要集成 jBPM,Spring 提供了很好的集成支持,那对于 Java EE 来说该怎么办呢?对于 jBPM 来说,你显然应该使用 JBoss 了。如果看看 JBoss 在常规的 Java EE 栈之上提供了什么,你就会发现他们提供了与自己的其他产品的很棒的集成支持,以注解的形式提供。你可以轻松将其与 Java EE 集成起来,就像与 Spring 集成一样。

额外的集成也有了,我觉得在平台的下一个版本中会有更多集成,因为 CDI 是进行依赖注入及与其他技术集成的一个非常重要的规范。我们看到这在 Java EE 中已经发生了,在 Java EE 7 中,它更棒了,我认为从长远来看,CDI 会成为添加到 Java EE 中的一门重要技术,因为它使得平台具有可扩展性。此外,Spring 栈还提供了 Java EE 中所没有的东西,比如说 NoSQL 集成或是社交集成等,我觉得这很好,听起来有些不可思议吧,因为无论是社交还是 NoSQL,现在都还没有形成标准,将尚未成熟的东西以标准化的形式纳入到 Java EE 中是个非常愚蠢的做法,有可能在 10 到 15 年后你会发现它并不是一个好标准。过去已经出现过这种情况,比如说老版本的 JSF。

我们已经从 EJB Entity Beans 上看到了这一点, 不是么?出于某些原因,愚蠢的想法将其纳入到了标准之中,现在已经很难再摆脱它了。在使用 EJB 时,我们不得不在 14 年的时间内使用 Entity Beans。一旦纳入到了标准当中就很难再将其剥离出去。因此,不要做不成熟的标准,不成熟的标准是万恶之源。创新应该通过开源来实现,或者通过 Spring 框架、或者通过 JBoss 正在做的某些开源实现、或者通过 Apache 项目、或者通过其他开源项目。当某个东西已经很棒了,人们开始使用它时就是进行标准化并将其纳入到 Java EE 当中之时。因此,Java EE 要比 Spring 滞后一些。Spring 的创新周期更快,不过 Java EE 的目标不在于创新,而是标准化,给予你一个企业栈,你可以使用它进行构建,如果需要任何特殊的特性,请将其放在标准之上。

InfoQ:照你这么说,设定规范的主要目的就是确保企业能在未来 10 年,甚至 15 年还能继续使用它?

Bert:没错,这就是兼容性!我想很多人会说,标准并不重要。不过我认为他们忽略了这重要一点,那就是标准可以确保长时间的兼容。如果现在选择 JPA,那么在未来 5 年,10 年内,你都可以使用 JPA。

InfoQ:对于 Web MVC 这一层次来说,Spring 提供了强大的 Spring MVC 框架,它也可以用做 RESTful Service。在 EE 6 中该如何实现呢,JSF 还是其他规范?

Bert:Java EE 6 自带了一个 Web 框架,即 Java Server Faces,如果想要进行 Web 开发,你可以使用它。它是一个基于组件的服务器端有状态的 Web 框架,不过并不是每个 Web 应用都适合。我认为你应该思考自己的 Web 应用要做什么。如果它是个基于请求响应的模型而不是基于组件的模型,那么你就不应该使用 JSF,而是使用其他 Web 技术。只有 JSF 才是 Java EE 一部分这个事实并不意味着就没有其他能与 Java EE 完美结合的 Web 框架可供我们使用了。事实上,现今已经有很多能与 Java EE 完美集成的 Web 框架。你可以使用 Vaadin、Wicket 或是 GWT 等 Web 框架,你可以在 Java EE 之上使用这些框架。对于 Restful Service 来说,Java EE 有 JAX-RS 这个 Restful Service 规范,你可以使用它进行 Web 开发。我们现在看到了一种趋势,当前的 Web 应用并没有使用服务器端的 Web 框架。他们将 Web 框架应该处理的任务从服务器端迁移到了浏览器端,使用强大的 JavaScript,特别是一些非常棒的 JavaScript MVC 框架,比如说来自 Google 的 AngularJS,你可以在浏览器端构建真正复杂的 Web 应用,只在浏览器上运行 HTML 5 与 JavaScript。为了调用服务器端,使用 JAX-RS 创建 Restful API,它就像服务器 API 一样提供 Restful Web Service。

我认为在未来几年中,我们会看到这样一种变迁,有状态的 Web 框架将会变得越来越少,也越来越不重要。这种 Web 应用的一切将会迁移到客户端,服务器将通过 Restful API 进行抽象。Java EE 将会成为后端栈。后端首先是个 Restful Web Service,然后是事务层,接下来是对象关系层,他们之间可能还会有其他东西。这正是 Java EE 真正强大之处,Web 真正强大之处在于运行着 HTML 5 的浏览器以及 Restful Web Service。

InfoQ:你认为迁移到前端是个好的趋势?

Bert:没错。这让服务器摆脱了大的有状态会话。有状态 Web 框架的一个问题在于他们无法伸缩。特别是对于新的应用来说,你需要处理大量用户与负载,保持无状态是最好的了;Web 层也总是充满了痛苦,因为如果有会话,那么 Web 层就会有大量状态。现在,如果可以摆脱这些会话,那么你可以将其替换为无状态的 Restful Service,然后将状态迁移到浏览器端,这是最合适的了,因为你可以使用一些新的 HTML 5 特性来处理离线 Web 内容;当连接到服务器时,你只需再次与后端同步即可。

我认为这是 Web 开发的一个趋势,你不必非得使用 JSF,JAX-RS 提供了 Rest 支持。不过 JSF 2.x 实际上是个相当不错的框架。如果只想为组件风格的 Web 应用寻找一个 Web 框架,那么你可以使用 JSF 2。它对 JSF 1 进行了大量改进。问题在于使用 JSF 替换掉完美的 Spring MVC 应用有意义么?肯定没有。如果你是不久前使用 Spring MVC 框架构建了 Spring 2.x 应用,那么替换成 JSF 是毫无意义的,因为 JSF 是个标准。这就是我一直在说的业务场景。如果有合适的业务场景,那么可以迁移,而不应该仅仅因为 JSF 是个标准就迁移。

InfoQ:当然了。Spring 提供了一个强大的测试框架以简化单元测试,我们可以使用模拟测试,因此就无需再启动服务器了,那么在 EE 6 中该如何实现呢,代价如何?

Bert:我们方才已经说过 Arquillian,我在演讲中所用的示例已经展示了如何测试 Java EE 中的数据访问对象。数据访问对象通过 JPA 访问数据库,那么你该如何为这些代码编写单元测试呢?如果模拟依赖,那么你需要模拟出 EntityManager,剩下的就是需要测试的一些空方法了。接下来你需要做的就是编写单元测试,测试 Java 是否能够调用某个方法。

这么做有点蠢。在 Java EE 环境中,你并不想要编写普通的单元测试,你希望针对业务逻辑的单元测试可以更容易地编写,由于 Java EE 现在有了 CDI 和依赖注入,你可以轻松地为这些 Bean 编写单元测试,就像为 Spring 编写测试那般简单。他们处于同一水平之上,对于存在依赖如 DAO 等的那些对象来说,他们也是差不多的。说完单元测试,下面来说说集成测试。你希望测试运行在容器中的代码,让容器中的所有服务都可用。借助于 Arquillian,你可以创建这些“微部署”,如果要测试 DAO,那就需要一个 DAO 对象,还需要包含着 DAO 的一两个实体,也许是其他类,然后将这 3、4 个类打包。接下来,创建应用的这个微部署,将其部署到正在运行着的应用服务器上,运行测试,然后卸载部署,应用服务器依然会保持运行。现在,微部署也有一些代价,不过代价并不高,现在运行测试就好像是运行 JUnit 测试一样,只不过这是应用的集成测试。因此,现在使用的还是 JUnit,你可以通过 IDE 获得反馈,要么条棒变绿,要么变红,它的运行与单元测试一样简单。

现在有很多人在使用 Maven,他们将单元测试与集成测试划分开来。单元测试是会频繁执行的,接下来为集成测试创建一个不同的 Maven 档案然后运行,每次进行重构你都会运行,或是每天至少在构建服务器上运行测试一次。你可以通过 Java EE 执行这两种类型的测试,不过 Java EE 中的某些东西只对应用服务器中的测试有意义,而这正是 Arquillian 发挥作用之处,只要保持部署足够小,它就能运作的很好。

InfoQ:相比于 EJB 2,新的 EJB 标准已经有了很大的改进。不过,使用 EJB 与 JPA 来替换掉 Spring 的数据访问集成或是事务管理真的有必要么,特别是在现有应用运行良好的情况下?

Bert:我之前其实已经回答了这个问题:这完全取决于业务场景。如果你最近在开发 Spring 应用,那么你可能已经在使用 Spring JPA 了,如果开发的时间稍微有些久,那么你可能使用的是 Spring Hibernate,并且应用也运行良好,你在这基础之上使用事务,而且对于目前的开发栈来说这依然是恰当的,那就没必要替换。

我认为只有在技术栈完全过时的情况下进行替换才是合理的。如果运行的是某些 JDO 实现,如 KODO,或是使用了老版本的 TopLink,那么我觉得替换才是有意义的,如果使用的是 JDBC 模板,那么我觉得你可以考虑升级成 JPA。如果看看最近的 Spring 栈,你会发现他们也升级为使用 JPA 了。重申一次,替换与否取决于业务场景,如果一切运转良好,那就没必要替换;如果现在有技术债务,如果有架构上的问题,那就有升级的理由了。EJB 与 JPA 有着良好的集成机制,最后的代码也比使用 Spring JPA 少很多,因为使用他们无需配置,或者是只需要很少的配置即可。

我展示了一些代码示例,使用了 EJB 与 JPA,代码量比使用 Spring 少了很多。如果需要,那就可以替换,理解这些代码是很轻松的事情。这些代码非常简洁,你不用再使用那么多代码了,同时在 EJB 方法中也有自动化的事务边界,这与 JPA 编程模型的集成堪称完美。

InfoQ:虽然 EE 6 发布已经有一段时间了,不过很多应用依然在使用 EE 5 甚至是 J2EE 1.4,这些应用也许使用的是 Spring,你对这怎么看?

Bert:没错,我觉得这些应用也需要升级。我的意思是如果在产品上有 J2EE 1.4 应用,那么它已经不再被支持了。如果是 J2EE 应用,那么它所运行的应用服务器厂商已经在升级了。因此它已经不再支持这些技术栈了,你应该对这些应用进行升级,这是完全不同的事情:如何从 J2EE 1.4 升级到 Java EE 6。

如果是运行在 Tomcat 上的 Spring 应用,而我有一个 J2EE 5 运行时,那么还应该考虑升级么?答案当然是不了。从 Spring 升级到旧版本的 Java EE 上是毫无意义的。我认为升级到 JavaEE 6 上才是有意义的,升级到 EE 5 或是 J2EE 1.4 上是没必要的。这是对第一个问题的回答。

InfoQ:你应该知道,在大公司中,迁移并不是一件容易的事情,特别是对于运行良好的应用来说更是如此。比如说,有一个运行在 Tomcat 上的 Spring 应用,你该如何说服公司高层将其迁移到 EE 6 上呢?如果迁移,那么我们还可能需要将服务器由 Tomcat 换成应用服务器,这很容易么?

Bert:如果问题是这样:我们有 Spring,有 Tomcat,想要迁移到 EE 6,可否?那么管理层可能会说不行。特别是有代价的情况下更是如此,对吧?你应该找到一个业务场景,该场景会在未来几年都会发挥作用,然后看看在现有的 Spring 应用上做维护以及继续在 Spring 栈上做新的开发的风险是什么?如果不确定 Spring 的未来会变成什么样子,而 Java EE 6 则得到了长足的进步,那么在未来几年中,寻找熟悉相关技术的开发者的难度将会增加。我们还能在未来几年中找到熟悉 Spring MVC 的开发者么?或者这么说,现在还能找到熟悉 KODO 的开发者么?

我觉得应该存在这种业务场景。在当前的栈上持续维护以及慢慢迁移到新的运行时上的代价分别是什么。从许可角度来看,Tomcat 是免费的,而 Java EE 应用服务器则是收费的。现在,已经有了很多开源的应用服务器了,质量都很不错,比如说 JBoss 或是 Glassfish,最近又有了 TomEE,它是带有一些 EE 扩展的 Tomcat,实现了 Java EE 6 Web Profile,Web Profile 是 Java EE 6 的一个子集,它已经提供了 EJB 的部分特性、CDI,还有其他特性。

你现在已经可以在 Tomcat 等轻量级容器上使用 Java EE 6 的一些强大的 Web 特性。对于方才提到的这些开源的应用服务器来说,你也可以免费使用。厂商也会提供某些订阅模式,你基本不需付费就可以获得某些支持。我的意思是这些支持模式并不贵。对于 Spring 来说,每个人都会比较简单的 Tomcat 与功能完善的应用服务器,在开发 Spring 应用时,你实际上将自己的应用服务器打包到了 WAR 文件中。我的意思是框架实现了事务、安全、池化、对象映射等等,你将这些东西放到了自己的应用中。你实际上是在 Tomcat 上运行着自定义的应用服务器,对于 Java EE 6 来说,这些东西则是在容器中。它已经是个应用服务器了,你只需在上面部署自己的代码即可。轻量级与重量级的比较是个没意义的讨论,你可以说他们都是轻量级的,也可以说他们都是重量级的。

InfoQ:说得好,最后一个问题是关于微服务器的发展趋势:现在我们趋向于每个应用服务器上部署一个应用而不是将多个应用部署到一个应用服务器上,人们会将所有东西放到一个 jar 中,然后快速部署。你是如何看待这个趋势的?

Bert:我认为应用服务器有应用域的概念,虽然在每个应用服务器上部署一个应用,但你依然可以创建这些域模型,这样可以在一个单独的域应用中管理所有这些独立的应用。这提供了一个很棒的管理模型,实际上我并没有看到这种部署模型有什么差别,无论是 Tomcat Spring 栈还是基于 Java EE 的应用服务器,我都没有看到有什么差别。我的意思是我们不应该再将应用服务器看作是一个庞然大物或是非常贵的东西。如果看看最近发布的 JBoss 或是 Glassfish,甚至是商业应用服务器,他们的启动时间变少了,占用的内存也变少了,因此启动多个实例是没问题的。你甚至可以在一台机器上运行这些实例,没问题的。他们只会启动应用所需要的那部分组件。如果没有使用 EJB 或是 Web 层,那么 Web 容器与 EJB 容器是不会启动的。

因此,我并不觉得这些部署方案存在什么差别。对于使用 Arquillian 进行测试的场景来说,你无需重启应用服务器,因为可以使用一个专门的应用服务器一直运行,如果需要集成测试,那么你可以执行微部署、运行测试,在测试完成后,可以自动卸载部署,应用服务器则会一直保持运行。也就是说,你无需重启应用服务器。Tomcat 也是如此,如果需要修改配置文件,你也需要重启 Tomcat。所以,我觉得对于这一点来说,Spring 与 Java EE 并没有什么差别。

InfoQ:谢谢你能接受我们的采访。