控制总线

企业集成模式 (EIP) 书中所述,控制总线的理念是,同一个消息系统可以用于监控和管理框架内的组件,也可以用于“应用程序级”消息传递。在 Spring Integration 中,我们基于上面描述的适配器,以便您可以发送消息作为调用公开操作的一种方式。

以下示例展示了如何使用 XML 配置控制总线

<int:control-bus input-channel="operationChannel"/>

控制总线有一个输入通道,可以访问该通道来调用应用程序上下文中的 Bean 上的操作。它还具有服务激活端点的所有通用属性。例如,如果操作的结果具有要发送到下游通道的返回值,则可以指定输出通道。

控制总线在输入通道上运行消息作为 Spring 表达式语言 (SpEL) 表达式。它接收一条消息,将消息体编译为表达式,添加一些上下文,然后运行它。默认上下文支持任何使用 @ManagedAttribute@ManagedOperation 注释的方法。它还支持 Spring 的 Lifecycle 接口(以及自版本 5.2 以来其 Pausable 扩展)上的方法,以及用于配置 Spring 的多个 TaskExecutorTaskScheduler 实现的方法。确保您自己的方法可用于控制总线的最简单方法是使用 @ManagedAttribute@ManagedOperation 注释。由于这些注释也用于将方法公开到 JMX MBean 注册表,因此它们提供了一个方便的副产品:通常,您希望公开给控制总线的相同类型的操作对于通过 JMX 公开是合理的)。应用程序上下文内任何特定实例的解析是在典型的 SpEL 语法中完成的。为此,请使用 SpEL 前缀为 Bean 提供 Bean 名称(@)。例如,要执行 Spring Bean 上的方法,客户端可以将消息发送到操作通道,如下所示

Message operation = MessageBuilder.withPayload("@myServiceBean.shutdown()").build();
operationChannel.send(operation)

表达式的上下文根是 Message 本身,因此您还可以访问表达式中的 payloadheaders 作为变量。这与 Spring Integration 端点中的所有其他表达式支持一致。

使用 Java 注释,您可以按如下方式配置控制总线

@Bean
@ServiceActivator(inputChannel = "operationChannel")
public ExpressionControlBusFactoryBean controlBus() {
    return new ExpressionControlBusFactoryBean();
}

类似地,您可以按如下方式配置 Java DSL 流定义

@Bean
public IntegrationFlow controlBusFlow() {
    return IntegrationFlow.from("controlBus")
              .controlBus()
              .get();
}

如果您更喜欢使用带有自动 DirectChannel 创建的 lambda,您可以按如下方式创建控制总线

@Bean
public IntegrationFlow controlBus() {
    return IntegrationFlowDefinition::controlBus;
}

在这种情况下,通道名为 controlBus.input