我在网上看到的大多数资源都是通过以下方式宣布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家工厂的不利之处是什么?

推荐答案

10年前,当我最初设计MessageChannels工厂时,它只打算作为Java DSL配置的流畅API内联使用.然后我意识到太多的方法链级会给代码留下意大利面的印象,所以我将该工厂作为公共API的所有ChannelSpec个实现.现在我们有一些 Select 来创建通道:通过它们的构造器或使用这个工厂.这在某些情况下仍然会造成一些困惑,因为最终用户面临着 Select 的悖论.这感觉就像你也撞到了.

enrichHeaders()和它的errorChannel()配置真的不同于IntegrationFlow.from()channel().这两个在配置阶段有影响,因此我们真的可以传递一个ChannelSpec,框架将为我们配置各自的Bean.

HeaderEnrichererrorChannel选项已经是关于将这样的头添加到消息传递中的运行时逻辑.因此,Spec不能在这里使用,因为我们在这里不处理配置阶段.

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

然而,正如你所看到的,它有一个缺陷,我们需要在运行时从名称中解析bean.特别是如果你谈论enrichHeaders():每个消息在运行时都将被修改为具有通道名称的头部.稍后这个名字将被解析为bean.

最有效的方法实际上是对通道Bean使用纯ctor:您拥有对对象的所有控制,并且不会受到MessageChannels工厂中缺少的一些API的影响.您可以将参数注入到IntegrationFlow Bean定义中,并在DSL中需要的任何时候使用此MessageChannel实例.这样,在运行时不会创建额外的Bean,也不会产生额外的逻辑.唯一的问题是,更多的编码.

在一切都是你自己的 Select 和惯例中.

注意:建议使用@Configuration(proxyBeanMethods = false),并且不要相互使用Bean方法引用:没有代理-没有额外的开销.

编辑:声明带有代理bean方法的IntegrationFlow禁用:

@Bean
IntegrationFlow myFlow(MessageChannel myErrorChannel, MessageChannel out) {
    IntegrationFlow.from(...)
        .enrichHeaders("errorChannel", myErrorChannel)
        .handle(...)
        .channel(out)
        .get();
}

@Bean
public MessageChannel myErrorChannel { return new DirectChannel(); }

@Bean
public MessageChannel out { return new DirectChannel(); }

Java相关问答推荐

我需要生成一个文件来整合每个特性执行的所有JSON结果

我找不到&Quot;配置&的位置

如何使用Maven和Spring Boot将构建时初始化、跟踪类初始化正确传递到本机编译

Java:使用Class.cast()将对象转换为原始数组

返回响应时,CamelCase命名约定不起作用

try 判断可选参数是否为空时出现空类型安全警告

每次FXMLLoader调用ApplationConext.getBean(类)时创建@Component的新实例

%This内置函数示例

在Oracle JDBC连接中,连接失效和身份验证失效是什么意思?

如何配置空手道以使用FeignClient或RestTemplate代替ApacheHttpClient

如果第一位数字和最后一位数字相差超过一位,您将如何获得随机数?

JFree Chart从图表中删除边框

如何处理两个几乎相同的XSD文件?

如何在SWT菜单项文本中保留@字符

在具有Quarkus Panache的PostgreSQL中将JSON数据存储为JSONB时,会将其存储为转义字符串

如何在Spring Boot中为不同的部署环境管理多个.properties文件?

整数->;双取消框,但双->;int不';t开箱.为什么?

验证没有';t work on Hibernate Entity';s字段

对于 Hangman 游戏,索引 0 超出长度 0 的范围

如何使用 Java 替换位于特定标记内的 XML 标记的 CDATA 内的值