Могу ли я получить доступ к бинам в области сеанса Spring из бинов в области приложения? Как? - PullRequest
2 голосов
/ 24 мая 2010

Я пытаюсь сделать это приложение для двух игроков, используя Spring MVC. У меня есть бины Player в области сеанса и бин GameList в области приложения, который создает и сохраняет Game экземпляры и передает их в Players. Игрок создает игру и получает ее идентификатор от GameList, а другой игрок отправляет идентификатор на GameList и получает экземпляр Game. Экземпляр Game имеет своих игроков в качестве атрибутов. Проблема в том, что каждый игрок видит только себя, а не другого.

Пример того, что видит каждый игрок:

  1. Первый игрок (Алиса) создает игру: Creator: Alice, Joiner: Empty
  2. Второй игрок (Боб) присоединяется к игре: Creator: Bob, Joiner: Bob
  3. Первый игрок обновляет свой браузер Creator: Alice, Joiner: Alice

Я хочу, чтобы они увидели Creator: Alice, Joiner: Bob. Простой способ добиться этого - сохранять информацию об игроках, а не ссылки на игроков, но игровой объект должен вызывать методы на своих объектах игрока, так что это не решение.

Я думаю, это из-за aop:scoped-proxy бина Player в сессионной области. Если я понимаю, объект Game имеет ссылку на прокси, который ссылается на объект Player текущего сеанса. Может ли экземпляр Game сохранять / получать доступ к другим объектам Player каким-либо образом?

бобов в dispatcher-servlet.xml:

<bean id="userDao" class="authorization.UserDaoFakeImpl"  />
<bean id="gameList" class="model.GameList" />
<bean name="/init/*" class="controller.InitController" >
     <property name="gameList" ref="gameList" />
     <property name="game" ref="game" />
     <property name="player" ref="player" />
</bean>
<bean id="game" class="model.GameContainer" scope="session">
      <aop:scoped-proxy/>
</bean>
<bean id="player" class="beans.Player" scope="session">
      <aop:scoped-proxy/>
</bean>

методы в controller.InitController

private GameList gameList;
private GameContainer game;
private Player player;
public ModelAndView create(HttpServletRequest request,
        HttpServletResponse response) throws Exception {        
    game.setGame(gameList.create(player));        
    return new ModelAndView("redirect:game");
}
public ModelAndView join(HttpServletRequest request,
        HttpServletResponse response, GameId gameId) throws Exception {
    game.setGame(gameList.join(player, gameId.getId()));       
    return new ModelAndView("redirect:game");
}

вызванные методы в model.gameList

public Game create(Player creator) {        
    Integer code = generateCode();        
    Game game = new Game(creator, code);
    games.put(code, game);
    return game;
}
public Game join(Player joiner, Integer code) {
    Game game = games.get(code);
    if (game!=null) {
        game.setJoiner(joiner);           
    }
    return game;
}

Ответы [ 4 ]

2 голосов
/ 24 мая 2010

Вы не можете получить доступ к различным bean-объектам в области сеанса из области приложения.

Однако вы могли бы поступить иначе - зарегистрировать каждого игрока в компоненте приложения (вызывая addPlayer(..))

1 голос
/ 24 мая 2010

Я верю, что вы правы насчет того, что прокси вы видите только себя. Любая ссылка на прокси будет применяться только к объекту в вашем сеансе.

Вам нужна игра и игрок как сессия ограничен? Факт что вы пытаетесь их использовать через сеансы указывает что они не являются данными области сеанса. Вы можете просто создать их на фабрике и сохранить их ссылки в bean-объекте сессий.

В качестве альтернативы, если вы хотите, чтобы у игрока была область видимости сеанса, вы можете поместить ссылку на прототип в сессионный компонент. Затем вы можете использовать ссылку на прототип для своих данных кросс-сессии и сессионный компонент для любых локальных данных, специфичных для сессии.

Существует несколько способов решения этой проблемы, но, по сути, вам необходимо переместить данные кросс-сеанса из bean-объектов области действия в компонент приложения, который можно использовать совместно.

0 голосов
/ 22 мая 2014

Да, и самый простой способ - создать прокси со следующей аннотацией:

@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)

Доступно с весны 3.1. В старые времена вам приходилось использовать тег aop: scoped-proxy в конфигурации XML

0 голосов
/ 24 мая 2010

Вы не можете хранить игровые данные в сеансе HTTP, поскольку они принадлежат только одному пользователю.

Ссылка на игру должна храниться как в сеансе создателя, так и в сеансе столяра.

...