开发者

Spring MVC: session beans from two different sessions

A (simplified) version of the problem I'm facing is as follows, in a Spring MVC application:

Two players can compete in a game. This game consist of starting from the same data (e.g. a certain chess position), playing the game seperately (but at the same time!) and comparing the results af开发者_开发问答terwards. To manage this I have:

  • An object that handles the game (e.g. checking if the players are ready, generating the start data, checking if the game is finished, ...). Let's call this the 'GameHandler' for easy referening.
  • For each player, an object that handles the game actions (e.g. moving a piece on the chess board). This is a session scoped bean, since it contains state information that is player-specific. Call this the 'PlayerHandler':

    <bean id="playerHandler" class="snip.PlayerHandler" scope="session"> <aop:scoped-proxy /> </bean>

The problem is that the GameHandler requires refences to both PlayerHandlers. However, since that's a proxy'd session scoped bean, those references are pointing to the same bean, depending on which session I use to access it. E.g. two players, "Tom" and "Jerry":

Session Tom: both playerHandler.getGameHandler().getPlayer1().getName() and playerHandler.getGameHandler().getPlayer2().getName() are Tom Session Jerry: both are Jerry.

Now, as I understand it, this is the expected behavior. My question is not "why is this", it's "how do I solve this". A solution that I found myself is to refer to the actual beans, not the proxies, when setting the references in the GameHandler:

public void setPlayerOne(PlayerHandler playerHandler) {
try {
        while (playerHandler instanceof Advised)
            playerHandler = (PlayerHandler ) ((Advised) playerHandler ).getTargetSource().getTarget();
    } catch (Exception e) {
        e.printStackTrace();
}
...

However, I am far from sure this is the best solution. So I'm looking for some answers: is my design wrong - if so, how would you design this? Did I miss a simple solution for this? Is this a Spring limitation?


Going back to your basic design, you'll have to reconsider if your "PlayerHandler" really is session scoped, conceptually. Since you require access to it outside the scope of a given session (a thread handling a request for a specific session), it looks like it is not.

One way to refactor this would be to move the "PlayerHandler" out to the application scope. Create a global singleton bean, call it "PlayerHandlerHolder" maybe, with a map that holds PlayerHandler instances keyed to session id, for instance. To prevent infinitely filling up this map, you could implement a session listener that removes PlayerHandler instances from the map on session destroy.


One way to solve your problem would be to create a custom scope, call it "game". Now define your bean like this:

<bean id="playerHandler" class="snip.PlayerHandler" scope="game">
<aop:scoped-proxy /></bean>
0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜