Обратный вызов внешнего потока в Spring bean-объект области видимости - PullRequest
2 голосов
/ 09 февраля 2012

У меня есть приложение Spring Web MVC, в котором мне нужно использовать драйвер внешнего устройства, который возвращает информацию асинхронным образом каждый раз, когда устройство собирает какие-то новые данные.Нам нужно передать объект в начале метода начала чтения.Этот объект реализует определенный API-интерфейс, который объявляет метод обратного вызова.

Проблема возникает, когда этому методу обратного вызова необходимо манипулировать некоторым bean-компонентом в области сеанса Spring.Поскольку обратный вызов вызывается в потоке драйвера, когда реализация обратного вызова хочет получить доступ к бину Spring, он выдает исключение, говорящее о том, что текущий поток не находится в управляемой области Spring.

Мне интересно, есть лиспособ превратить объект, который реализует интерфейс обратного вызова, в некий прокси-сервер, который знает информацию о контексте сеанса, который его сконструировал, чтобы таким образом он мог вызывать методы бина через объект контекста Spring?

1 Ответ

0 голосов
/ 09 февраля 2012

Я думаю, что вы подходите к проблеме не с той стороны. Я думаю, вы хотите, чтобы обратный вызов драйвера устройства внес некоторые результаты в пользовательский сеанс. Но этого недостаточно для отображения этих данных, поэтому (опять-таки догадываясь), вероятно, требуется некоторый длительный опрос, изучающий сеанс с помощью bean-объекта сессионной области.

Исходя из этого предположения, я советую вам генерировать какой-то уникальный requestId каждый раз, когда вы вызываете внутренний драйвер и помещаете его requestId как в сеанс HTTP, так и в обратный вызов. Когда вызывается обратный вызов, он помещает результаты в какую-то карту, где ключу назначается requestId. Теперь клиент (который также знает requestId) может посмотреть на карту и получить результаты. Вы должны помнить о синхронизации (что также имеет место с обычной HttpSession).

Если у вас есть более продвинутый способ уведомления клиентов (Comet? WebSockets?), Это также можно сделать с помощью этого обратного вызова.

Обратите внимание, что технически вы можете передать экземпляр объекта HttpSession в экземпляр обратного вызова (но, как вы можете видеть, это не работает с bean-объектами в сессионной области Spring), но передача сеанса вокруг не выглядит хорошим дизайном. Просто лучше обеспечить уровень косвенности. Что если в будущем вы захотите повторно использовать этот код с помощью командной строки или настольного клиента?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...