我的同事说我使用本地 EJB 不是一个好主意
我强烈不同意这一点。本地 EJB是一个非常好的主意,因为它们是实现业务逻辑的完美 bean 类型。当前的 EJB bean 产量非常轻,因此您不必因为任何所谓的重量级而避免使用它们。
这些类型的 bean 的最大优势可能是它们的自动事务管理,在执行任何类型的数据库工作时都会派上用场。
这不仅仅是需要访问 JMS 队列和复杂的 EIS 系统的企业应用程序。任何一次对数据库进行多次写入的 Web 应用程序都会从中受益匪浅。如果没有事务,您最终会说User
,每当发生异常或崩溃时,它只保留在数据库中的一半。如果没有 EJB,您将不得不在您的代码中添加大量非常冗长的start\commit\rollback
语句,更不用说将您的事务(通常通过“连接”)传播到您的所有代码中,并且在事务处于或不处于活动状态时有单独的情况。
使用 EJB bean,所有这些复杂性都消失了。这就像垃圾收集与手动内存管理。
还有很多其他有趣的功能,即使是最简单的 Web 应用程序也可以使用,例如声明性角色检查 ( @RolesAllowed
)、bean 池(以限制吞吐量等)和线程安全。
在 Java EE 6 中,它们确实变得更易于用于简单的 Web 应用程序,并且它们可以出现在 .war 中的任何地方(不再需要单独的 .jar 和伞形 .ear)。
所以我很困惑:何时使用 GWT Servlet(它比简单的 HTTPServlet 更方便,它提供 RPC 样式的方法调用)以及何时使用 EJB?
所以现在我们正在谈论远程 EJB。在这种情况下,答案是不同的。
如果客户端从 Internet 连接,您几乎不会使用远程 EJB。通常需要打开大量端口,包括客户端上的端口。
同样,如果您有异构客户端(.NET、C++ 甚至 Java 客户端,它们运行与远程 EJB 使用的 AS 版本略有不同的版本),您通常不会使用远程 EJB。
尽管理论上支持 Corba (IIOP) 并因此允许不同类型的客户端,但实际上远程 EJB 通信仅在客户端和服务器都运行 Java 并且除了相同的 AS(应用程序服务器)或其中之一是 Java SE 客户端时才有效使用远程服务器的客户端库(可能很大)。
对于远程技术来说这有点尴尬,但是 EJB 规范甚至没有指定如何首先设置远程连接。事实上的标准是远程 JNDI,但由于这不是规范,JBoss 例如希望在 JBoss AS 7 中停止支持它。
在所有这些情况下,您将使用一种Web Service
技术而不是远程 EJB。GWT Servlet
可能是一种选择,但在这里并不是一个真正的典型例子。除非您已经在使用 GWT,否则我不建议仅将它安装用于来自任意(非 GWT)客户端的一般 web/rpc 连接。
一般的 Java 解决方案是 JAX-WS 和 JAX-RS,它们是 SOAP 和 REST 实现(两者都可以与 EJB 结合使用)。众所周知的 JAX-RS 实现是Jersey(示例)和RestEasy。在 Java EE 6 中,您不必为它们安装任何东西,因为它们已经是平台的一部分。对于 Java EE 5,您必须单独安装 JAX-RS,但 JAX-WS 已经存在。
人们通常会发现 JAX-RS 更容易上手和更现代的方法,尽管 JAX-WS 具有更多内置的类型安全特性(这也正是其大部分复杂性的来源)。
最后,我们什么时候使用远程 EJB?通常,您会为运行相同 AS 的本地网络上的应用程序之间的通信执行此操作。在这种情况下,有潜在的性能优势(二进制序列化可以比 json/xml 转换更快),并且有一些强大的选项用于传播安全上下文和协调分布式事务。简单的 Web 应用程序很可能不需要经常使用最后一个功能(如果有的话)。
一种常见的模式是 JAX-RS 资源(bean)模式,它接受来自远程(Web)客户端的请求,然后将工作委托给包含实际业务逻辑的本地 EJB。