Spring MVC: сессионные компоненты двух разных сессий - PullRequest
1 голос
/ 22 августа 2011

(упрощенная) версия проблемы, с которой я сталкиваюсь, в приложении Spring MVC выглядит следующим образом:

В игре могут участвовать два игрока.Эта игра состоит из того, чтобы начать с одних и тех же данных (например, с определенной шахматной позиции), сыграть в игру отдельно (но в то же время!) И сравнить результаты после этого.Для этого у меня есть:

  • Объект, который управляет игрой (например, проверка готовности игроков, генерация стартовых данных, проверка завершения игры, ...).Давайте назовем это «GameHandler» для легкого обращения.
  • Для каждого игрока, объект, который обрабатывает игровые действия (например, перемещение фигуры на шахматной доске).Это bean-объект сессионной области, так как он содержит информацию о состоянии, которая зависит от игрока.Назовите это PlayerHandler:

Проблема в том, что GameHandler требует отсылки к обоим PlayerHandler.Однако, поскольку это сессионный компонент с прокси-сферой, эти ссылки указывают на один и тот же компонент в зависимости от того, какой сеанс я использую для доступа к нему.Например, два игрока, «Том» и «Джерри»:

Сессия Том: оба playerHandler.getGameHandler().getPlayer1().getName() и playerHandler.getGameHandler().getPlayer2().getName() - это Том Сессия Джерри: оба - Джерри.

Теперь, насколько я понимаюЭто ожидаемое поведение.Мой вопрос не «почему это так», а «как мне решить эту проблему».Решение, которое я нашел, заключается в том, чтобы ссылаться на фактические компоненты, а не на прокси, при установке ссылок в GameHandler:

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

Однако я далеко не уверен, что это лучшее решение.Поэтому я ищу ответы на некоторые вопросы: мой дизайн неправильный - если да, то как бы вы это разработали?Я пропустил простое решение для этого?Это весеннее ограничение?

Ответы [ 2 ]

1 голос
/ 22 августа 2011

Возвращаясь к вашему базовому дизайну, вам придется пересмотреть, концептуально ли ваш PlayerHandler действительно ограничен сессией.Поскольку вам требуется доступ к нему вне области данного сеанса (поток, обрабатывающий запрос для определенного сеанса), похоже, что это не так.

Один из способов рефакторинга - переместить PlayerHandler."в область применения.Создайте глобальный одноэлементный компонент, назовите его «PlayerHandlerHolder», возможно, с картой, в которой, например, содержатся экземпляры PlayerHandler, привязанные к идентификатору сеанса.Чтобы предотвратить бесконечное заполнение этой карты, вы можете реализовать слушатель сеанса, который удаляет экземпляры PlayerHandler из карты при уничтожении сеанса.

0 голосов
/ 22 августа 2011

Один из способов решения вашей проблемы - создать пользовательскую область действия , назовите ее «игра».Теперь определите ваш боб так:

<bean id="playerHandler" class="snip.PlayerHandler" scope="game">
<aop:scoped-proxy /></bean>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...