无法自动装配。找不到SimpMessagingTemplate类型的bean。

20

我基本上是按照文档中提供的指南配置Spring中的Websockets。

我目前正在尝试像“从任何地方发送消息”一节中所述那样,从服务器向客户端发送消息。

按照示例,您可以自动装配一个名为SimpMessagingTemplate的类。

@Controller
public class GreetingController {

    private SimpMessagingTemplate template;

    @Autowired
    public GreetingController(SimpMessagingTemplate template) {
        this.template = template;
    }

    @RequestMapping(value="/greetings", method=POST)
    public void greet(String greeting) {
        String text = "[" + getTimestamp() + "]:" + greeting;
        this.template.convertAndSend("/topic/greetings", text);
    }

}

然而,我的当前项目无法找到bean“SimpMessagingTemplate”。(Intellij:“无法自动装配。找不到SimpMessagingTemplate类型的bean。”)
我已经查看了互联网上的几个示例,但我无法找到如何让Spring创建SimpMessagingTemplate实例的方法。如何进行自动装配?
编辑:
我决定发送一些更多的背景信息。这是我的当前websocket配置:
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:websocket="http://www.springframework.org/schema/websocket"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/websocket
        http://www.springframework.org/schema/websocket/spring-websocket-4.0.xsd">

        <!-- TODO properties to be read from a properties file -->
        <websocket:message-broker application-destination-prefix="/app">
            <websocket:stomp-endpoint path="/new_session" >
                <websocket:sockjs/>
            </websocket:stomp-endpoint>
            <websocket:simple-broker prefix="/topic"/>
        </websocket:message-broker>
</beans>

Websocket与此控制器配合使用

@Controller
public class SessionController {

    private static final Logger log = LoggerFactory.getLogger(SessionController.class);

    @MessageMapping("/new_session")
    @SendTo("/topic/session")
    public SessionStatus newSession(Session session) throws Exception {
    Thread.sleep(3000); // simulated delay
    log.info("Response sent !!");
    return new SessionStatus("StatusReport, " + session.toString() + "!");
    }
}

我不确定如何让这个工作起来

public class SessionController {

    private static final Logger log = LoggerFactory.getLogger(SessionController.class);

    private SimpMessagingTemplate template;

    @Autowired
    public SessionController(SimpMessagingTemplate template) {
    this.template = template;
    }

}

由于找不到豆子“SimpMessagingTemplate模板”,Spring文档没有提供更多有关此事的细节。

编辑github中的工作代码示例。

5个回答

19

我遇到了同样的问题,这是因为我的websocket配置文件出错:

@Configuration
@EnableWebSocketMessageBroker
@EnableScheduling
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

}

未被Spring扫描到。

因此,解决方法是将此配置文件的包添加到已扫描的包中。


我知道我晚了几年,但这解决了我的问题! - Rodrigo Silveira

6

很奇怪,因为当您使用websocket命名空间时,“message-broker”元素会导致创建SimpMessagingTemplate bean,该bean应该可用于注入。控制器和websocket命名空间是否在同一个ApplicationContext中,或者其中一个在“root”上下文中,另一个在DispatcherServlet上下文中?


2
谢谢你的帮助。我找到了问题所在。我写了一个代码证明,然后意识到问题是Intellij没有正确地捕捉到SimpMessagingTemplate的@Autowire。如果你现在运行程序,它会正常工作。 - Tk421
2
@plkmthr 这个问题是Intellij没有正确识别SimpMessagingTemplate。如果你运行它,它会工作的。请检查“代码证明”的链接。 - Tk421
现在我正在抑制所有试图进行自动装配的类的警告,但我不喜欢这样做。 - systemhalted
1
如果被压制了就不起作用。但有一个例外:com.example.socketdemo.controllers.DemoController 构造函数的参数0需要一个类型为 org.springframework.messaging.simp.SimpMessagingTemplate 的bean,但是找不到该bean。 - qwert_ukg

5
你应该在applicationContext xml文件中,要么使用与类名相同的bean定义id,要么在被注入的类上添加@Component注释,以使自动装配生效。
<bean id="SimpMessagingTemplate " class="your-class" >

您可能需要定义下面的标签来指向您的包以备后用。
<context:component-scan base-package="com.x.y"/>

5
请注意,SimpMessagingTemplate不是我的类,而是Spring框架的一部分。文档没有提供有关如何获取该类实例的更多信息。如果我尝试像这样在我的XML中添加bean:<bean id="simpMessagingTemplate" class="org.springframework.messaging.simp.SimpMessagingTemplate"/>,则会期望构造函数(MessageChannel接口)中提供一个参数,但我不确定如何将其链接到当前的websocket配置。 - Tk421
我有更多与此问题相关的问题。http://stackoverflow.com/questions/23026408/how-to-use-executorsubscribablechannel - Tk421

1
罗森是正确的。添加元素将向上下文中添加SimpMessagingTemplate bean以进行注入。这必须在Web应用程序根上下文中,而不是Spring DispatchServlet的上下文中。例如,在以下web.xml文件中,message-broker元素应包含在app-root.xml文件中。仅包含在app-mvc.xml中会导致NoSuchBeanDefinitionException异常。
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/spring/app-root.xml</param-value>
</context-param>

<servlet>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:/spring/app-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

0
在我的情况下,我通过在pom.xml中添加Spring-Boot-Starter-Websocket的依赖来修复了错误。尽管我在类中已经导入了SimpMessagingTemplate,但它仍然需要在pom.xml中添加依赖。
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接