【问题标题】:Spring Integration using DirectChannel in IntegrationFlow throws "Dispatcher has no subscribers"在 IntegrationFlow 中使用 DirectChannel 的 Spring Integration 抛出“Dispatcher 没有订阅者”
【发布时间】:2022-01-27 07:58:38
【问题描述】:

我使用 Spring Integration Java DSL 对 IntegrationFlow 进行了这个非常基本的设置:

@IntegrationComponentScan
@EnableIntegration
@Configuration
public class DummyConfig {

    @MessagingGateway
    public interface DummyGateway {
        @Gateway(requestChannel = "dummyInChannel")
        void echo(String payload);
    }

    @Bean(name = "dummyInChannel")
    public MessageChannel dummyInChannel() {
        return MessageChannels.direct().get();
    }

    @Bean
    public IntegrationFlow dummyFlow() {
        return IntegrationFlows.from(dummyInChannel())
            .handle(String.class, (payload, headers) -> {
                System.out.println(payload);
                return "";
            })
            .get();
    }

}

当我尝试向我的网关发布消息时

dummyGateway.echo("test");

我得到了异常:

Caused by: org.springframework.messaging.MessageDeliveryException: 
Dispatcher has no subscribers for channel 'application.dummyInChannel'.; nested exception 
is org.springframework.integration.MessageDispatchingException: Dispatcher 
has no subscribers, failedMessage=GenericMessage [payload=test, 
headers={replyChannel=nullChannel, id=6e4302e4-95f0-bf5a-c1a3-e8cd587c23fb, timestamp=1643269549272}]

我想,在我的流程中执行.handle() 就是订阅频道。那么,为什么我会得到这个异常?在这种情况下如何正确订阅我的频道?

【问题讨论】:

  • 如果你改为IntegrationFlows.from("dummyInChannel"),它会如何工作?
  • @ArtemBilan 我遇到了与IntegrationFlows.from("dummyInChannel") 完全相同的异常。
  • 哦!请告诉我们,你什么时候打电话给dummyGateway.echo("test");。您不会在应用程序生命周期中过早地这样做吗?您真的要等到应用程序上下文完全准备好了吗?
  • 我在另一个 @Component 的构造函数中执行此调用,它依赖于我的 DummyConfig.DummyGateway,所以我假设应用程序上下文已经初始化。顺便说一句,如果我将频道类型更改为 MessageChannels.queue().get() 它可以工作。
  • 这在上下文生命周期中还为时过早。

标签: java spring spring-integration spring-integration-dsl


【解决方案1】:

不,演员为时过早。此时创建了 bean,但它们还没有开始繁重的工作。您不能从 bean 初始化阶段进行低级资源交互(技术上是任何操作)。您需要等到应用程序上下文完全启动。请学习 Spring 容器的生命周期:https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-factory-lifecycle-processor

您可以实现SmartLifecycle,或ContextStartedEvent 的侦听器。但是 bean 初始化阶段开始发送消息还为时过早。

QueueChannel 之所以有效,是因为它有自己的内部缓冲区来保存消息直到它们被使用。它们在端点启动时被消耗。在DirectChannel 的情况下,没有缓冲区,当我们发送消息时会立即调用消费者。在 bean 初始化阶段,该频道上还没有订阅者。

【讨论】:

    【解决方案2】:
    public static void main(String[] args) {
            SpringApplication application = new SpringApplication(DummyConfig.class);
            ConfigurableApplicationContext ctx = application.run(args);
             ctx.getBean(DummyGateway.class).echo("MyAwesomeString");
            ctx.close();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-05
      • 2021-01-31
      • 2020-09-09
      • 1970-01-01
      • 2017-08-23
      • 2019-10-04
      • 2018-09-17
      • 2019-10-12
      相关资源
      最近更新 更多