在根据《Spring In Action》中内容,实践“使用STOMP消息”的过程中,遇到下面的问题:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.messaging.simp.SimpMessagingTemplate' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1644)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1203)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1164)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:593)
... 62 more
经过探索,导致该问题出现的原因是:将STOMP的配置放在了Spring的DispatcherServlet上下文中。正确的是应该讲该配置放到ContextLoaderListener 上下文中。
如下是Java的正确配置方式(详细代码,在github上:STOMPSpringMarcopolo )
/**
* 配置Spring
* @Date 2019-05-01
* @Author lifei
*/
@Configuration
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
/**
* 配置ContextLoaderListener 上下文
* @return
*/
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{RootConfig.class, WebSocketStompConfig.class};
}
/**
* 配置DispatcherServlet 上下文
* @return
*/
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{WebConfig.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
/**
* @Date 2019-05-01
* @Author lifei
*/
@Configuration
@EnableWebSocketMessageBroker // 启用STOMP消息, 表明这个配置类不仅配置了WebSocket, 还配置了基于代理的STOMP消息
public class WebSocketStompConfig implements WebSocketMessageBrokerConfigurer {
.....
}