是否可以使容器将相同的有状态会话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 ?
答案 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来存储您的州。