将@Stateful或@Stateless注入@Singleton EJB

时间:2016-06-13 08:11:30

标签: java-ee dependency-injection singleton ejb stateful

我有一个@Singleton EJB,我在其中注入另一个 Singleton的EJB(它是@Stateless或@Statefull)。 E.g。

@Singleton
public class MySingleton {
    @EJB
    MyStatefulBean statefulBean;//this is stateful!

    public void doSomething() {
        statefulBean.something();
    }
}

我的问题是:statefulBean总是会有相同的引用,或者每次调用doSomething()时它会有什么不同吗?由于我们有一个单例,因此statefulBean始终具有相同的引用是有意义的。不过,我问,因为我是EJB的新手,并且想要确定。谢谢!

2 个答案:

答案 0 :(得分:1)

每次调用doSomething时,您都会statefulBean与之相关联 当前会话负责此单例调用。在方法执行期间,您锁定了Singleton ejb,而没有其他锁定 可以在具有的对象旁边调用此Singleton ejb的方法 直接引用此ejb通常是ejb对象self,因为其他 对象获取代理对象引用。此外,在方法执行期间 没有其他对象可以注入此ejb。这是可能的,因为 singleton是为并发访问和默认并发设置而设计的 Singleton ejb是ConcurrencyManagementType.CONTAINERLockType.WRITE。 您可以更改此行为,但请记住,然后您使用Singleton ejb可以同时从多个线程调用,你可以得到 如果你注入statefull对象,意外的结果是特殊的。 More about concurrency control of singleton ejb's you can read there.

答案 1 :(得分:0)

  

我的问题是:statefulBean总是会有相同的引用,或者每次调用doSomething()时它会有什么不同吗?

以下是EJB specification对此的陈述:

  

3.4.7.1状态会话Bean

     

有状态会话对象具有唯一标识,该标识在创建对象时由容器分配。有状态会话Bean业务接口的客户端可以使用equals方法确定两个业务接口或无接口视图引用是否引用同一会话对象。

     

例如,

@EJB Cart cart1;

@EJB Cart cart2;

...

if (cart1.equals(cart1)) { // this test must return true
    ...  
}
...

if (cart1.equals(cart2)) { // this test must return false
    ...
}
     

对同一有状态会话Bean实例的同一业务接口的所有有状态会话Bean引用都是相同的。对同一有状态会话bean实例的无接口视图的所有引用都是相同的。对不同接口类型或接口类型与无接口视图或不同会话bean实例之间的有状态会话Bean引用将不具有相同的标识。

这意味着一旦客户端获得对有状态会话bean的引用,该bean就会绑定到客户端。客户端可以设置和读取bean的状态。当客户端完成时,它必须通过调用由@Remove注释注释的方法来通知服务器应该销毁该bean。