开发者

Possible to inject same stateful session bean instance into multiple other session beans?

Is it possible to make the container inject the same stateful session bean instance into multiple other stateful session beans?

Given the following classes:

@Stateful
public class StatefulTwoBean implements StatefulTwo {

    @EJB
    private StatefulOne statefulOne;

}

@Stateful
public class StatefulThreeBean implements StatefulThree {

    @EJB
    private StatefulOne statefulOne;

}

In the above example, StatefulTwoBean and StatefulTh开发者_JS百科reeBean each get injected their own instance of StatefulOneBean.

Is it possible to make the container inject the same instance of StatefulOneBean into both StatefulTwoBean and StatefulThreeBean?


The problem is this - Stateful beans' isntances are allocated by differentiating the clients that call them. Glassfish (and perhaps others) don't propagate this difference on injected beans. The EJB specification, as far as I remember, isn't clear about this.

So your solution is to implement the differentiation yourself. How to achieve this. I'm not pretending this is the most beautiful solution, but it worked. - we did it by putting a Facade (an EJB itself) (I'm calling it a facade, although it does not entirely cover the facade pattern) in front of all our EJBs, with the following code:

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);
    .....
}

The important parameter is sessionId - this is something both the client and the server know about, and identifies the current seesion between them.

On the client we used a dynamic proxy to call this facade. So the calls look like this: getBean(MyConcreteEJB.class).someMethod(), an the getBean method created the proxy, so that callers didn't have to know about the facade bean.

The SessionRegistry had

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

And the SessionContext was simply a Map providing set(key, value) and get(key)

So now, instead of using @Stateful beans to store your state, you could use the SessionContext.


In EJB3.1 you can create your StatefulOne bean as singleton (using the @Singleton annotation) giving you the desired semantics. JBoss should already support this annotation (they've wrote the standard).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜