Control Bus

Enterprise Integration Patterns (EIP)书中所述,控制总线背后的想法是,可以将相同的邮件系统用于监控和管理框架内的组件,就像用于 “application-level” 邮件一样。在 Spring 集成中,我们在上面介绍的适配器的基础上构建,以便您可以发送邮件作为调用公开操作的一种方式。

以下示例演示了如何使用 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 语法实现的。要做到这一点,请为 Bean 提供带有 Bean 的 SpEL 前缀 (@)。例如,为了在 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