2012-01-29 63 views
7

到目前为止,我几乎总是使用无接口的EJB,并且对@Local注释的需求有了一些了解。考虑下面这个例子:EJB 3.1。是否需要@Local注释?

public interface MyBeanIntf { void doStuff(); } 

@Stateless 
public class MyBean implements MyBeanIntf { public void doStuff(){ } } 

如若MyBeanIntf被标记为@Local?我没有看到来自任何好处,因为即使当我不标注它作为@Local,我仍然可以使用DI妥善它注入到UI控制器:

@Named 
@SessionScoped 
public class TestController implements Serializable { 

    // injection works perfectly, even when MyBeanIntf is not marked as @Local 
    @Inject 
    private MyBeanIntf myBean; 

    // or even like this: 
    // @EJB 
    // private MyBeanIntf myBean; 

} 

让我们更加复杂:

public interface MyBeanIntf { void doStuff(); } 
public class MySuperBean implements MyBeanIntf { public void doStuff() { } } 

@Stateless 
public class MyBean extends MySuperBean { } 

MyBean现在认为是有效的Local EJB bean?我有一些疑问,因为它间接地实现了接口。

回答

8

如果你的EJB实现了一些接口,但你没有指定(在EJB和接口本身)接口它是(@Remote,@Local)的接口,而不是它假设它是@Local接口。

因此您的代码:

public interface MyBeanIntf { void doStuff(); } 

@Stateless 
public class MyBean implements MyBeanIntf { public void doStuff(){ } } 

在语义上等同于以下内容:

@Local 
public interface MyBeanIntf { void doStuff(); } 

@Stateless 
public class MyBean implements MyBeanIntf { public void doStuff(){ } } 

当涉及到你问题的第二部分,我认为部分4.9.2.1会话Bean来自EJB 3.1 FR spec的超级类对您有用。从我的理解(所以它可能是不正确的),似乎你的bean不应被视为暴露,因为以下摘录的一个有效的本地接口:

@Stateless 
public class A implements Foo { ... } 

@Stateless 
public class B extends A implements Bar { ... } 

假设Foo和Bar是本地业务接口并且没有相关的部署描述符 ,会话bean A公开本地 业务接口Foo和会话bean B公开本地业务 接口Bar,但不是Foo

会话bean B将需要明确地将Foo包含在其要应用的该接口的暴露视图的集合 中。

更新:

作为补充,从规范多了一个摘录:

会话bean类可以有属于自己 会话bean类的超类。但是,对于这种情况,没有适用于注释处理或部署 描述符的特殊规则 。为了处理特定的会话bean类,,所有的超类处理都是相同的,不管 是否超级类本身是会话bean类。

+0

感谢您的回答。至于说明的链接,我仍然有一些疑问。它明确地讨论了超类,它们本身就是会话bean。但是如果它们只是没有'@ Stateless'或'@ Stateful'注解的抽象类呢? – jFrenetic 2012-01-29 12:26:49

+0

当然,我不确定100%,但看看编辑后的文章 - 也许它会有所帮助。 – 2012-01-29 12:48:47

+1

感谢您的重视。我自己阅读了这部分内容,但不知何故错过了它。 – jFrenetic 2012-01-29 13:11:17