2009-12-10 112 views
1

是否有可能让容器将相同的有状态会话bean实例注入多个其他有状态会话Bean?可能将相同的有状态会话bean实例注入到多个其他会话bean中?

考虑以下类:

@Stateful 
public class StatefulTwoBean implements StatefulTwo { 

    @EJB 
    private StatefulOne statefulOne; 

} 

@Stateful 
public class StatefulThreeBean implements StatefulThree { 

    @EJB 
    private StatefulOne statefulOne; 

} 

在上面的例子中,StatefulTwoBeanStatefulThreeBean分别获得注入的StatefulOneBean自己的实例。

是否有可能使容器注入相同的实例StatefulOneBean到StatefulTwoBean和StatefulThreeBean

+0

什么是您的应用程序服务器。 – Bozho 2009-12-10 15:16:27

+0

@Bozho为什么要麻烦? – 2009-12-10 16:14:00

+2

@Pascal,好吧,我曾经研究过一个类似的问题,并发现WebLogic(如果我记得没错的话)有一些实现他想要的功能。那时我正在使用Glassfish(不能)。因此,如果他的应用程序服务器是glassfish,我可以查看代码库并找到适合他的问题:) – Bozho 2009-12-10 16:27:05

回答

2

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

所以你的解决方案是自己实现差异化。如何实现这一点。我不假装这是最美丽的解决方案,但它的工作。

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); 
    ..... 
} 
: - 我们通过把一个门面(一个EJB本身)(我称它是门面,虽然它不完全覆盖门面模式)在我们所有的EJB的前面,用下面的代码做了

重要的参数是sessionId - 这是客户端和服务器都知道的事情,并确定它们之间的当前见解。

在客户端,我们使用动态代理来调用这个门面。所以调用如下所示: getBean(MyConcreteEJB.class).someMethod(),getBean方法创建代理,以便调用者不必知道门面bean。

SessionRegistry

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

而且SessionContext只是所以现在提供set(key, value)get(key)

一个地图,而不是使用@Stateful豆来存储你的状态,你可以使用SessionContext

2

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

+0

这个单身人士有那么多的范围?应用程序广泛还是像有状态bean那样绑定到客户端? – Sylar 2009-12-11 07:26:11

+1

@Sebastian:单例bean被定义为具有广泛的应用范围。对于会话范围,就像您已经提到的那样,您必须改用会话bean。 – jawi 2009-12-11 07:56:14