从jar和IntelliJ运行时,Spring按不同的顺序自动装配Bean-无法启动Bean'subProtocolWebSocketHandler'没有处理程序

问题描述

我正在构建一个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如何在没有修复的情况下成功运行该应用程序。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...