为什么EJB 3.0会话Bean需要单独的远程和本地接口?

38
我在想为什么EJB 3.0会需要分别的远程和本地接口。我猜大多数情况下它们都定义了相同的规范,为什么不能有一个公共的接口,然后在我的Bean中只需指定我希望访问该Bean的方式是远程、本地或者两者兼备。
谢谢 Vikas
6个回答

15

以下是EJB规范所述:

在开发企业Bean时,本地和远程编程模型之间的选择是Bean提供者所做的设计决策。
虽然可以为企业bean提供远程客户端视图和本地客户端视图,但通常只提供其中一种

JSR220第3章

因此,在编写Bean时,请考虑客户端是谁,很少有本地客户端需要相同的方法或甚至相同的Bean。


12

我不同意在设计时将远程和本地视为可以轻易互换的。

首先,远程调用会产生额外开销,因此在设计远程接口时,需要仔细考虑参数大小和粒度是否正确。因此,在设计时提醒这将比较昂贵是有帮助的。

此外,由于远程接口参数按值传递,而本地接口参数按引用传递,因此两种情况之间存在基本的语义差异,因此您可能会选择以不同的方式设计这两个接口。


我同意在许多情况下,我可能需要为两者设计不同的接口,但在我有相同接口的情况下,我应该能够用本地和远程进行注释。这样做的好处是我的客户端不必担心它是本地调用还是远程调用(除非他正在指定jndi名称)。它将在两种情况下获得相同的接口,因此可以同等对待它们。 - Vikas Kedia
1
好的,无论是好是坏,规范的作者们并不认为这种“本地/远程独立性”是可取的。就个人而言,我更倾向于支持规范作者的看法。 - djna

8
“位置透明”的概念是一个危险的反模式。出于许多原因(错误处理和性能最为显著),您的设计绝对需要知道它是在进行本地调用还是远程调用。
远程EJB接口与其本地对应物不同,因为异常签名需要不同以适应只能在远程调用中发生的与网络相关的错误。将远程处理负担放在本地接口上(这是EJB 1的情况)会使代码变得可怕。EJB 2引入了单独的本地接口,以简化始终为本地的EJB的编程。

1
我认为问题是,为什么在声明注入时我不能选择这个? - Mykola Golubyev

2

客户端通过bean的接口访问会话或实体bean。EJB容器生成接口实现来强制和管理此行为,充当客户端和bean之间通信的媒介。在EJB 2.0规范之前的版本中,所有bean都被定义和实现为分布式远程组件。因此,bean所需的两个接口被称为home接口(一般定义生命周期方法)和remote接口(一般定义功能业务方法)。

 Internally, J2EE uses the Java Remote Method Invocation over Internet Inter-ORB Protocol (RMI-IIOP) to enable remote, distributed method calls and applications. While this approach provides many benefits, it also generates a large amount of overhead, with a corresponding performance hit as stubs are referenced, parameters go through the marshaling process, and objects are tossed around the network.

 Considerations of performance, practicality, and typical usage in the field resulted in the introduction of local interfaces in the EJB 2.0 specification. As noted, prior terminology referred to the home interface and the remote interface; at this point, depending on which approach is used, local interface and local home interface or remote interface and remote home interface are better terms. Either of the local home or remote home interfaces is referred to as the home interface; either of the local or remote interfaces is referred to as the component interface. This tutorial refers to the interfaces in these terms and uses these conventions for names.

 When using J2EE technologies, it is normal to focus on distributed, or remote, beans, but you should keep the local option in mind, when applicable. It may be surprising to learn that a bean can have local interfaces, remote interfaces, or both. However, the client must write to a specific (that is, local or remote) interface. There are some issues to keep in mind when using local interfaces:

这些bean必须在同一个虚拟机中运行,因为它们是本地的。参数通过引用发送而不是被复制,就像远程接口和对象一样。如果您忽略这个区别并且没有相应地编码,可能会导致意外的副作用。

通常,使用本地访问还是远程访问受以下因素的影响:

客户端的类型 - 除非您总是期望客户端是Web组件或另一个bean,请选择远程访问。

bean之间的耦合程度 - 如果bean彼此依赖并频繁交互,请考虑使用本地访问。

可扩展性 - 远程访问本质上是可扩展的,并且如果可扩展性是重要因素,则应该使用远程访问。随着EJB 2.0规范中本地接口的出现,大多数来源建议实体bean几乎总是基于本地访问。使用本地接口,关于非常细粒度数据访问的大多数性能问题都消失了。如果客户端是远程的,则标准设计模式要求客户端使用远程接口访问会话bean,然后会话bean充当与实体bean进行联络的联络员。会话bean通过本地接口与实体bean通信(从模式的角度来看,这种技术称为会话外观,并且实际上可以在远程或本地上下文中使用)。


1
不错的文本,除了会话Bean不能与实体Bean通信。也许名称有点令人困惑,但现在会话Bean通过实体管理器来获取(JPA)实体。 - Arjan Tijms

2
我认为,当您的业务需要将所有方法在本地使用的同时也需要暴露给远程客户端时,可以采取以下步骤:
1. 在本地定义接口及其方法。 2. 在远程接口中继承本地接口并保留空实现。 3. 将所有业务逻辑和其他实现放在本地。 4. 远程bean实现只需委托给本地bean实现。
这种方法可以实现@Local和@Remote对同一接口的访问。如果需要,在本地和远程都可以访问相同的方法,而无需任何性能开销。
以上是我的想法,请告诉我您的想法以验证此方法是否可行。

这是一个有趣的想法,你是否发现你的想法是正确的?它实际上不会产生额外开销。我对此有类似的问题,https://dev59.com/H1jUa4cB1Zd3GeqPP0ii。我希望你能在这里提供一些想法。非常感谢。 - Thang Pham

1
一个很好的理由是因为你通过它的接口访问EJB。这样,当使用远程接口时,您通过值传递参数,而在使用本地接口时,则通过引用传递参数。你知道这种行为的原因吗?这是有道理的:也许你确实希望远程应用程序访问你的业务对象,并且因为通过引用传递可以减少网络延迟。请记住:远程访问涉及将对象转换为字节流(编组)以及将字节流转换为对象(解组)的过程。这个额外的步骤——编组和解组——会降低应用程序的性能。

我想你可能打得有点快,因为传递引用是减少网络流量的方式,而不是传递值(细节问题):) - ᴠɪɴᴄᴇɴᴛ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接