2016-01-13 5 views
2

Я разрабатываю Java webapp с Spring в качестве основной структуры (Spring core, Spring mvc, Spring security, Spring data, Spring websocket).Spring: как выставить SimpMessagingTemplate bean в корневой контекст?

Объявление message-broker в контексте Spring, как это обеспечивает SimpMessagingTemplate боб в контексте:

<websocket:message-broker> 
    <websocket:stomp-endpoint path="/stomp"> 
     <websocket:sockjs/> 
    </websocket:stomp-endpoint> 
    <websocket:simple-broker prefix="/topic,/queue"/> 
</websocket:message-broker> 

я должен поставить этот тег в dispatcher-servlet.xml (не applicationContext.xml), в противном случае клиенты получат 404 при попытке подключитесь к websocket (при начальной загрузке страницы).

Однако, так как этот тег, который обеспечивает SimpMessagingTemplate боб (для отправки сообщений подключенных клиентов) не доступен в корневом контексте, когда услуга (отсканированная корневой контекст) посылает сообщение WebSocket, то SimpMessagingTemplate компонент может не быть автомобильный (классический NoSuchBeanDefinitionException).

Ранее <websocket:message-broker> тега был в applicationContext.xml и dispatcher-servlet.xml импортировала applicationContext.xml и все работает отлично - однако я обнаружил, к моему удивлению, что это неправильно, когда я недавно использовал SessionRegistry для изменения произвольных пользовательских сеансов.

Действительно, так как DispatcherServlet был явно импортировать корневой контекст, который уже унаследованный неявный, то SessionRegistry боб был создан в два раза, что приводит к неожиданному поведению (есть несколько сообщений на SO, которые изображают эту распространенную ошибку, как правило, пользователи хотят получите список всех участников, но получите пустые списки из-за дублирования боба и узнайте об этом).

Так, чтобы исправить это я удалил

<import resource="applicationContext.xml"/> 

с диспетчерским-servlet.xml, но с тех пор:

  • либо я поставил <websocket:messagebroker>...</> тег в диспетчерском-servlet.xml, и в этом случае соединения с websocket успешны, но службы не могут автоопределить SimpMessagingTemplate
  • или я положил тег <websocket:messagebroker>...</> в applicationContext.xml, и в этом случае клиенты не могут подключиться к websoc кет.
  • (или я вернуться к предыдущей версии, где DispatcherServlet импорт ApplicationContext, который ломает SessionRegistry - Неа)

Что такое решение этой, вероятно, довольно распространенной проблемой? DispatcherServlet может получить доступ к компонентам из корневого контекста, но не наоборот, поэтому как мне это решить?

+0

Я экспериментировал с помещением всего из applicationContext.xml в диспетчер-сервлет, но тогда Spring-security не может использовать факсимильные компоненты, которые были объявлены в корневом контексте, что в основном является одной и той же проблемой :) – niilzon

ответ

0

Я нашел грязное решение. Мне это не нравится, но, учитывая отсутствие ответов на SO (см. Также: Dispatcher-servlet cannot map to websocket requests), а также от нынешних и бывших коллег, мне пришлось идти вперед с проектом и реализовывать грязное исправление.

Грязная исправить это AutowireSimpMessagingTemplate в контроллере и Запланированные классов (все сканируется dispatcher-servlet, где websocket tag объявлена), и передать SimpMessagingTemplate в качестве параметра к методам обслуживания (объявленной в root context).

Это решение не прозрачно (SimpMessagingTemplate должно быть автоматически передано непосредственно в сервисах), но это определенно устраняет проблему.

+0

Это боль. Я использую аналогичное решение: используйте @PostConstruct, а затем установите его в Service. – user1633272

Смежные вопросы