Java 从jar与IntelliJ运行时,Spring会以不同的顺序自动连接bean-无法启动bean';子目录WebSockEthandler';没有处理程序
我正在构建一个SpringWebSocket应用程序,我面临以下问题 当我使用IntelliJ运行应用程序时,一切正常,应用程序启动正常 当我使用SpringBootMaven插件构建胖jar并使用Java 从jar与IntelliJ运行时,Spring会以不同的顺序自动连接bean-无法启动bean';子目录WebSockEthandler';没有处理程序,java,spring,spring-boot,intellij-idea,classpath,Java,Spring,Spring Boot,Intellij Idea,Classpath,我正在构建一个SpringWebSocket应用程序,我面临以下问题 当我使用IntelliJ运行应用程序时,一切正常,应用程序启动正常 当我使用SpringBootMaven插件构建胖jar并使用java-jar启动应用程序时,应用程序无法启动,出现以下错误 无法启动bean“subtocolwebsockethandler”;嵌套异常为java.lang.IllegalArgumentException:无处理程序 在org.springframework.web.socket.messag
java-jar
启动应用程序时,应用程序无法启动,出现以下错误
无法启动bean“subtocolwebsockethandler”;嵌套异常为java.lang.IllegalArgumentException:无处理程序
在org.springframework.web.socket.messaging.subtocolwebsockethandler:start()上
我的SpringWebSocket配置如下所示
@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);
}
}
在DelegatingWebSocketMessageBrokerConfiguration中,这会导致无处理程序
错误。当我通过IntelliJ启动应用程序时,情况正好相反,一切正常
有人知道为什么会发生这种情况吗?原因可能是什么
是否有可能在jar中加载类路径的顺序与IntelliJ中加载的顺序不同,从而混淆了spring
编辑 我的
WebSocketConfig
类与我上面提到的略有不同。我正在使用setter注入自动连接WebSocketMessageBrokerStats。我已经更新了上面的代码。我没有在最初的问题中提到这一点的原因是我认为它无关紧要。但事实并非如此。答案就在下面
提前多谢
(如果您希望我方提供更多技术细节,请告知我)
Nick所以在玩了我的代码之后,我发现问题在于
WebSocketMessageBrokerStats
bean的注入。显然,这导致WebSocketConfig
bean(这是一种特殊类型的配置,因为它实现了websocketmessagebrokerconfigure
)在Spring上下文初始化的稍后阶段准备就绪,List configurers
在被registerStompEndpoints()
检查时为空
因此,解决方案是创建第二个配置类,并将WebSocketMessageBrokerStats
bean及其上的所有操作移动到新的配置文件中
上面正在修复jar文件,我可以使用
java-jar运行它,但是我不知道IntelliJ如何能够在没有修复的情况下成功运行应用程序。我可以在@Configuration
注释中看到WebSocketConfig
类。它符合@Component
或@Service
类的条件,因此它应该在setConfigurers
列表中作为bean自动连接,对吗?是的,它不会解决您的问题,但因为您是自动连接的,所以它应该是Component@autowired(required=false)
为什么不需要它?不确定为什么spring将其作为可选项。我确实重写了该方法,并使其成为必需的,但没有任何区别。
@Override
protected void registerStompEndpoints(StompEndpointRegistry registry) {
for (WebSocketMessageBrokerConfigurer configurer : this.configurers) {
configurer.registerStompEndpoints(registry);
}
}