问题描述
我正在构建一个Spring Web套接字应用程序,并且面临以下问题。
当我使用IntelliJ运行应用程序时,一切都很好,并且应用程序启动也很好。
当我使用Spring Boot Maven插件构建胖子并使用java -jar
启动应用程序时,应用程序无法启动并出现以下错误
Failed to start bean 'subProtocolWebSocketHandler'; nested exception is java.lang.IllegalArgumentException: No handlers
在org.springframework.web.socket.messaging.SubProtocolWebSocketHandler:start()
我的spring web socket配置看起来像这样
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
private WebSocketMessageBrokerStats webSocketMessageBrokerStats;
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic")
.setHeartbeatValue(new long []{webSocketsProperties.getClientHeartbeatsSecs() * 1000,webSocketsProperties.getServerHeartbeatsSecs() * 1000})
.setTaskScheduler(heartBeatScheduler());
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/gs-guide-websocket").setAllowedOrigins("*").withSockJS();
}
@Autowired
public void setWebSocketMessageBrokerStats(WebSocketMessageBrokerStats webSocketMessageBrokerStats) {
this.webSocketMessageBrokerStats = webSocketMessageBrokerStats;
}
}
发生上述错误的原因是因为当我使用jar运行应用程序时,方法
@Autowired(required = false)
public void setConfigurers(List<WebSocketMessageBrokerConfigurer> configurers) {
if (!CollectionUtils.isEmpty(configurers)) {
this.configurers.addAll(configurers);
}
}
在应该自动装配我的WebSocketConfig
的DelegatingWebSocketMessageBrokerConfiguration内部
@Override
protected void registerStompEndpoints(StompEndpointRegistry registry) {
for (WebSocketMessageBrokerConfigurer configurer : this.configurers) {
configurer.registerStompEndpoints(registry);
}
}
DelegatingWebSocketMessageBrokerConfiguration中的导致no handlers
错误。当我通过IntelliJ启动应用程序时,这是相反的情况,一切都很好。
有人知道这是为什么发生的,可能是什么原因造成的吗?
是否有可能在jar中加载类路径的顺序与在IntelliJ中以不同的顺序发生并且会使spring混乱?
编辑
我的WebSocketConfig
类与上面的内容略有不同。我正在使用setter注入自动WebSocketMessageBrokerStats
进行接线。我已经更新了上面的代码。我之所以没有在最初的问题中提到这个问题,是因为我认为这无关紧要。但事实并非如此。答案在下面...
非常感谢
(让我知道您是否需要我的更多技术细节)
尼克
解决方法
因此,在玩完我的代码后,我发现问题出在WebSocketMessageBrokerStats
bean的注入上。显然,这导致WebSocketConfig
bean(这是一种特殊的配置类型,因为它实现了WebSocketMessageBrokerConfigurer
)在Spring Context Initialization的后期准备就绪,而List<WebSocketMessageBrokerConfigurer> configurers
被检查时为空由registerStompEndpoints()
。
因此解决方案是创建第二个配置类,并将WebSocketMessageBrokerStats
bean及其上的所有操作移到新的配置文件中。
以上内容已修复了jar文件,我可以使用java -jar
运行它,但是我不知道IntelliJ如何在没有修复的情况下成功运行该应用程序。