EJB 3.1.是否需要@Local注释?

jFr*_*tic 7 ejb-3.1 glassfish-3

到目前为止,我几乎总是使用无接口EJB,并且对@Local注释的需求略有了解.考虑这个例子:

public interface MyBeanIntf { void doStuff(); }

@Stateless
public class MyBean implements MyBeanIntf { public void doStuff(){ } }
Run Code Online (Sandbox Code Playgroud)

应该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;

}
Run Code Online (Sandbox Code Playgroud)

让它变得更复杂:

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

@Stateless
public class MyBean extends MySuperBean { }
Run Code Online (Sandbox Code Playgroud)

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

Pio*_*cki 8

如果您的EJB实现了某个接口,但是您没有指定(在EJB和接口本身上)它是哪个接口(@Remote,@ Local),而不是它假定它是@Local接口.

因此你的代码:

public interface MyBeanIntf { void doStuff(); }

@Stateless
public class MyBean implements MyBeanIntf { public void doStuff(){ } }
Run Code Online (Sandbox Code Playgroud)

在语义上与以下内容相同:

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

@Stateless
public class MyBean implements MyBeanIntf { public void doStuff(){ } }
Run Code Online (Sandbox Code Playgroud)

当谈到问题的第二部分时,我认为来自EJB 3.1 FR规范的第4.9.2.1会话Bean超类对您来说很有意思.从我的理解(因此它可能不正确),似乎您的bean不应被视为暴露有效的本地接口,因为以下摘录:

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

@Stateless
public class B extends A implements Bar { ... }
Run Code Online (Sandbox Code Playgroud)

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

会话bean B需要在其应用的接口的暴露视图集中显式包含Foo.

更新:

另外还有一个来自规范的摘录:

允许会话bean类具有自己的会话bean类的超类.但是,对于此案例,没有适用于注释处理或部署描述符的特殊规则.出于处理特定会话bean类的目的,无论超类本身是会话bean类,所有超类处理都是相同的.