声明 MessageChannel beans 的首选方式

问题描述 投票:0回答:1

我在网上看到的大多数资源都是通过以下方式声明

MessageChannel
的:

@Bean
MessageChannel myChannel() {
    return new MessageChannels.direct().get();
}

似乎

.get()
方法已被弃用,并注明框架将在时间到时自动获取对象。一些较新的示例已声明消息通道 bean 以返回规范:

@Bean
DirectChannelSpec myChannel() {
    return new MessageChannels.direct();
}

在大多数情况下仍然可以引用

mychannel()
,因为 IntegrationFlow.from() 允许您传入 Spec 而不是实际通道。但是,在某些情况下,不支持传递规范。我遇到的一种情况是使用
.enrichHeaders
指定错误通道。我只能传入 MessageChannel 本身或消息通道名称作为字符串。

在这种情况下,现在的一般做法是仅使用消息通道的字符串名称吗?或者我应该声明一个仅使用通道构造函数的 bean?

@Bean
MessageChannel certainErrorChannel() {
    return new DirectChannel();
}

不使用

Spec
工厂有什么缺点?

java spring-boot spring-integration spring-integration-dsl
1个回答
0
投票

当我 10 年前最初设计

MessageChannels
工厂时,它的目的只是作为 Java DSL 配置的流畅 API 内联使用。然后我意识到太多的方法链级别会给代码带来意大利面条式的印象,所以我将该工厂作为公共 API 的所有
ChannelSpec
实现。现在我们可以选择创建通道:通过它们的构造函数或使用这个工厂。在某些情况下,这仍然会引起一些混乱,因为最终用户面临着选择的悖论。感觉你也撞到了。

enrichHeaders()
和它的
errorChannel()
配置确实不一样,什么是
IntegrationFlow.from()
channel()
。这两个在配置阶段起作用,因此我们确实可以传递一个
ChannelSpec
,框架将为我们配置各自的bean。

errorChannel
HeaderEnricher
选项已经与运行时逻辑有关,以将这样的标头添加到消息传递中。因此
Spec
不能在这里使用,因为我们不在这里处理配置阶段。

到处传递频道名称是非常方便的方法。首先:它使流程定义易于阅读。其次,如果通道在配置阶段不退出,它将被创建(如果我们真的谈论配置组件)。通道名称在运行时解析为其 bean。

但是,正如您所看到的,它有一个缺陷,我们需要在运行时从名称解析 bean。特别是如果您谈论

enrichHeaders()
:运行时的每条消息都将针对带有通道名称的标头进行修改。稍后该名称将被解析为 bean。

最有效的方法实际上是对通道 bean 使用普通的 ctor:您拥有对对象的所有控制权,并且不会遭受

MessageChannels
工厂中缺少某些 API 的困扰。您可以使用参数注入到
IntegrationFlow
bean 定义中,并在 DSL 中需要时使用此
MessageChannel
实例。这样就不会创建额外的 bean,并且在运行时也不会产生额外的逻辑。只是更多编码的问题。

一切都是你自己的选择和约定。

注意:建议使用

@Configuration(proxyBeanMethods = false)
并且不要使用彼此的 bean 方法引用:没有代理 - 没有额外的开销。

© www.soinside.com 2019 - 2024. All rights reserved.