EJB 3.1 @LocalBean与无注释


77

我了解本地视图,远程视图和无接口视图之间的区别。我只是不了解“无视图”(无注释)和无界面视图之间的区别。以及为什么还要用注释我的界面@Local?如果我根本不注释接口怎么办,有什么区别吗?


如果不全部注释,它将变成什么样的EJB bean?或者换句话说,容器如何知道一个类是POJO还是SessionBean?
esej 2012年

2
@esej您可以使用无状态,有状态或Singleton注释对其进行注释,然后使用Local,Remote或LocalBean注释对其进行注释,或者不使用此类注释对其进行注释。因此,当您使用无状态,有状态或单例注释对其进行注释时,容器便知道该类是否为SessionBean。
VaclavDedik 2012年

正确。(以前我没看清您的想法是什么,现在我变得更加明智了(因为我有一个奇怪的主意)。)
esej 2012年

我认为缺少注释意味着没有接口视图。因此,“无视图”和无界面视图没有区别!
Tom Anderson

Answers:


139

规则是(从内存中):

  1. Bean具有@LocalBean注释-> Bean具有无接口视图
  2. Bean具有@Local注释-> Bean具有本地视图
  3. Bean具有@Remote注释-> Bean具有远程视图
  4. Bean没有视图注释,但是直接实现一个具有@Local注释的接口-> Bean具有本地视图
  5. Bean没有视图注释,但是直接实现一个具有@Remote注释的接口-> Bean具有远程视图
  6. Bean没有视图注释,但是直接实现了一个没有视图注释的接口-> bean具有本地视图
  7. Bean没有视图注释,并且没有实现任何接口-> Bean具有无接口视图

因此,完全使用@LocalBean和不使用任何注释都是获取无接口视图的两种方式。如果只需要无接口视图,那么最简单的方法就是不添加注释。如果您还没有实现任何接口。

部分原因@LocalBean是要向还具有接口视图的Bean添加无接口视图。我认为规范作者认为最重要的场景是您有一个像这样的bean的场景:

@Stateless
public class UserPreferences {
    public String getPreference(String preferenceName);
    public Map<String, String> getPreferences();
}

您希望在本地公开这两种方法,但仅在getPreferences()远程公开粗粒度的地方。您可以通过仅使用该方法声明一个远程接口,然后@LocalBean对bean类打耳光来做到这一点。没有它,您将不得不编写一个无意义的本地接口,只是要在本地公开这两种方法。

或者换一种方式来看,@LocalBean之所以存在,是因为存在诸如无接口视图之类的东西,并且无注释选项作为方便的快捷方式存在。


9
确切的规则在EJB 3.1规范的4.9.7节中。它们比您提供的内容(家庭,Web服务,java.io / javax.ejb接口排除项)稍微复杂一些,但这是一个不错的总结。
Brett Kail 2012年

@bkail:感谢您的参考。我没有方便的规范副本,当我尝试下载规范时,Oracle的站点停止了,因此无法进行检查。我已经意识到,这是我需要阅读的领域!
汤姆·安德森

我认为。POJO是LocalBean吗?
bitli 2014年

@bitli:如果POJO没有实现任何接口,也没有注释,则它具有无接口视图,就像用注释一样@LocalBean
汤姆·安德森

16
  • 远程EJB:可以从远程客户端(运行在不同JVM上的客户端(例如在用户计算机上运行的Swing或JavaFX客户端)访问)
  • 本地EJB:只能从运行在同一JVM上的其他“组件”(例如Web前端,其他EJB)进行访问
  • 无接口视图:与本地相同,但未指定业务接口
  • 没有注释:简单的POJO但不是EJB

本地/无接口视图比远程EJB更有效,因为可以传递对象引用。


2
我认为当您使用无状态,Statefull或Singleton注释对POJO进行注释时,POJO就变成了EJB。我想念什么吗?
VaclavDedik 2012年

1
@Puce,您说“没有注释:一个简单的POJO但没有一个EJB”,这与汤姆·安德森(Tom Anderson)的评论矛盾:“如果POJO没有实现任何接口,并且没有注释,那么它将具有无接口视图,就像它用@LocalBean注释”。你能澄清一下吗?
bigfoot '18

6

我认为您/我们所感到的困惑是历史/可追溯性(可以这么说)的结果。我无法分辨出任何区别(除非规范要求实现(如果我们使用本地视图,则必须创建接口))

无接口视图的行为与EJB 3.0本地视图相同,例如,它支持诸如按引用传递调用语义以及事务和安全性传播之类的功能。但是,无接口视图不需要单独的接口,也就是说,bean类的所有公共方法都会自动向调用者公开。缺省情况下,任何具有空的Implements子句且未定义任何其他本地或远程客户端视图的会话Bean都会公开无接口客户端视图。

EJB 3.1发行之前的Oracle Blog


0

如果您对更多技术细节感兴趣,那么我可以说真正发生了什么...。您没有直接访问EJB对象的权限,这意味着您没有实际EJB对象的引用(地址)。当您查找或注入EJB时,容器将提供一个对象作为该EJB的客户端(我们可以称为代理或包装器),并且您可以在该代理对象上调用业务方法。(这就是为什么您不应该使用new关键字来创建EJB类的对象的原因)

现在,对于每种类型的注释,容器都会使用不同的方法和功能生成不同类型的代理。

@LocalBean (或没有注释)您的代理对象具有:

  • setOptionalLocalIntfProxy()
  • getSerializableObjectFactory()

@Local 您代理对象使用本地调用和类型,com.sun.proxy因此它具有:

  • getSerializableObjectFactory()
  • isProxyClass()
  • getProxyClass()
  • getInvocationHandler()
  • newProxyInstance()

@Remote 包装器对象使用远程调用,它具有:

  • readResolve()
  • writeReplace()
  • getStub()
  • getBusinessInterfaceName()
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.