Spring 在 IntegrationFlow 中使用 DirectChannel 的集成抛出 "Dispatcher has no subscribers"
Spring Integration using DirectChannel in IntegrationFlow throws "Dispatcher has no subscribers"
我有这个 IntegrationFlow
的非常基本的设置 Spring 集成 Java DSL:
@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();
}
}
当我尝试post向我的网关发送消息时
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()
就是订阅一个频道。那么,为什么我会收到此异常?在这种情况下如何正确订阅我的频道?
不,ctor 太早了。此时创建了 bean,但它们还没有开始繁重的工作。您不能从 bean 初始化阶段进行 low-level 资源交互(技术上任何操作)。您需要等到应用程序上下文完全启动。请了解 Spring 容器的生命周期:https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-factory-lifecycle-processor .
您可以实施 SmartLifecycle
或 ContextStartedEvent
的侦听器。但是 bean 初始化阶段开始发出消息真的太早了。
QueueChannel
之所以有效,是因为它有自己的内部缓冲区来保存消息,直到它们被使用。并且它们在端点启动时被消耗掉。在 DirectChannel
的情况下,没有缓冲区,当我们发送消息时,消费者会立即被调用。在 bean 初始化阶段,该频道上还没有订阅者。
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();
}
我有这个 IntegrationFlow
的非常基本的设置 Spring 集成 Java DSL:
@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();
}
}
当我尝试post向我的网关发送消息时
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()
就是订阅一个频道。那么,为什么我会收到此异常?在这种情况下如何正确订阅我的频道?
不,ctor 太早了。此时创建了 bean,但它们还没有开始繁重的工作。您不能从 bean 初始化阶段进行 low-level 资源交互(技术上任何操作)。您需要等到应用程序上下文完全启动。请了解 Spring 容器的生命周期:https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-factory-lifecycle-processor .
您可以实施 SmartLifecycle
或 ContextStartedEvent
的侦听器。但是 bean 初始化阶段开始发出消息真的太早了。
QueueChannel
之所以有效,是因为它有自己的内部缓冲区来保存消息,直到它们被使用。并且它们在端点启动时被消耗掉。在 DirectChannel
的情况下,没有缓冲区,当我们发送消息时,消费者会立即被调用。在 bean 初始化阶段,该频道上还没有订阅者。
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();
}