
在这样的Spring上下文中声明一个消息代理,为上下文提供了一个SimpMessagingTemplate bean:
<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)中,否则客户端在尝试连接到websocket时会获得404(在初始页面加载时).
但是,由于此提供SimpMessagingTemplate bean的标记(向连接的客户端发送消息)在根上下文中不可用,因此当服务(由根上下文扫描)发送websocket消息时,SimpMessagingTemplate bean无法自动装配(经典NoSuchBeanDefinitionException) ).
以前,< websocket:message-broker> tag在applicationContext.xml中,dispatcher-servlet.xml正在导入applicationContext.xml,一切正常 – 但是当我最近使用SessionRegistry修改任意用户会话时,我发现这是错误的.
实际上,由于DispatcherServlet明确地导入了已经隐含继承的根上下文,因此SessionRegistry bean被创建了两次,导致意外的行为(SO上有几个帖子描述了这个常见的错误,通常用户希望得到一个列表所有主体但由于SessionRegistry bean重复而获得空列表并找到相关信息.
所以为了解决这个问题,我删除了
<import resource="applicationContext.xml"/>
来自dispatcher-servlet.xml,但从那时起:
>要么我把< websocket:messagebroker> …< />在dispatcher-servlet.xml中标记,在这种情况下,与websocket的连接成功但服务无法自动装配SimpMessagingTemplate
>或者我把< websocket:messagebroker> …< /> applicationContext.xml中的tag,在这种情况下客户端无法连接到websocket.
>(或者我回到之前的版本,其中DispatcherServlet导入ApplicationContext,它打破了SessionRegistry – nope)
这可能是一个相当常见的问题的解决方案是什么? DispatcherServlet可以从根上下文访问bean,反之则不然,所以我应该如何处理?
脏修复是在Controller和Scheduled类中自动装配SimpMessagingTemplate(所有都由dispatcher-servlet扫描,其中声明了websocket标记),并将SimpMessagingTemplate作为参数传递给服务方法(在根上下文中声明).
这个解决方案不透明(SimpMessagingTemplate应该直接在服务中直接自动装配),但它肯定能解决问题.
转载注明原文:xml – Spring:如何将SimpMessagingTemplate bean暴露给root上下文? - 乐贴网