可以将同一个有状态会话bean实例注入多个其他会话bean吗?

时间:2009-12-10 15:14:05

标签: java ejb-3.0

是否可以使容器将相同的有状态会话bean实例注入多个其他有状态会话bean?

鉴于以下类别:

@Stateful
public class StatefulTwoBean implements StatefulTwo {

    @EJB
    private StatefulOne statefulOne;

}

@Stateful
public class StatefulThreeBean implements StatefulThree {

    @EJB
    private StatefulOne statefulOne;

}

在上面的示例中, StatefulTwoBean StatefulThreeBean 每个都会注入自己的 StatefulOneBean 实例。

是否可以让容器将 StatefulOneBean 相同实例注入 StatefulTwoBean StatefulThreeBean

2 个答案:

答案 0 :(得分:2)

在EJB3.1中,您可以将StatefulOne bean创建为单例(使用@Singleton注释),为您提供所需的语义。 JBoss应该已经支持这个注释(他们已经编写了标准)。

答案 1 :(得分:2)

问题在于 - 通过区分调用它们的客户端来分配有状态bean的状态。 Glassfish(也许还有其他人)不会在注入的豆子上传播这种差异。据我所知,EJB规范对此并不清楚。

所以你的解决方案是自己实现差异化。如何实现这一目标。我不是假装这是最美丽的解决方案,但它有效。 - 我们通过在所有EJB前面放置一个Facade(一个EJB本身)(我称之为外观,虽然它并不完全覆盖Facade模式),并使用以下代码:

public Object call(Object bean,
        String methodName,
        Object[] args,
        Class[] parameterTypes,
        UUID sessionId) throws Throwable {

    //find the session
    SessionContext sessionContext = SessionRegistry.getSession(sessionId);
    //set it as current
    SessionRegistry.setLocalSession(sessionContext);
    .....
}

重要参数是sessionId - 这是客户端和服务器都知道的内容,并标识它们之间的当前信号。

在客户端上,我们使用动态代理来调用此Facade。所以调用看起来像这样: getBean(MyConcreteEJB.class).someMethod(),getBean方法创建了代理,因此调用者不必了解Facade bean。

SessionRegistry

private static ThreadLocal<SessionContext> localSessionContext = new 
   ThreadLocal<SessionContext>();

SessionContext只是提供set(key, value)get(key)

的地图

现在,您可以使用@Stateful而不是使用SessionContext bean来存储您的州。