跳到主要内容
版本:7.0.2

控制总线

DeepSeek V3 中英对照 Control Bus

正如《企业集成模式》(EIP)一书所述,控制总线的核心理念在于:用于“应用级”消息传递的同一消息系统,也可用于监控和管理框架内的组件。在 Spring Integration 中,我们基于上述适配器进行构建,使您能够通过发送消息来调用已暴露的操作。

important

由于控制总线功能强大,足以改变系统状态,建议对其消息接收进行安全加固(参见 SecurityContextChannelInterceptor),并仅将控制总线管理(消息源)暴露在 DMZ 区域中。

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

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

控制总线具有一个输入通道,可用于调用应用程序上下文中bean的操作。它还具备服务激活端点的所有通用属性。例如,如果操作结果具有返回值且您希望将其发送到下游通道,则可以指定一个输出通道。

控制总线在输入通道上以托管操作的形式运行消息,消息格式为简单的字符串,例如 beanName.methodName。目标方法参数的参数必须作为列表在 IntegrationMessageHeaderAccessor.CONTROL_BUS_ARGUMENTS 头部中提供。要调用的 bean 和方法由 ControlBusCommandRegistry 基础设施 bean 解析。默认情况下,ControlBusCommandRegistry 按需注册命令:可以通过 @EnableIntegrationManagement(loadControlBusCommands = "true") 开启其 eagerInitialization 标志。

控制总线(Control Bus)的功能与 JMX 类似,因此,方法要成为命令必须满足以下要求:

  • 已使用 @ManagedAttribute@ManagedOperation 注解的方法;

  • Spring 的 Lifecycle 接口(及其自 5.2 版本起新增的 Pausable 扩展);

  • 用于配置多个 Spring TaskExecutorTaskScheduler 实现的方法。

确保您自己的方法对控制总线可用的最简单方式是使用 @ManagedAttribute@ManagedOperation 注解。由于这些注解也用于向 JMX MBean 注册表暴露方法,它们提供了一个便捷的副产品:通常,您希望暴露给控制总线的操作类型也适合通过 JMX 暴露。更多信息请参阅 ControlBusCommandRegistryControlBusMethodFilter 的 Javadoc 文档。

要执行 Spring Bean 上的方法,客户端可以向操作通道发送消息,如下所示:

Message<?> operation = MessageBuilder.withPayload("myServiceBean.shutdown").build();
operationChannel.send(operation);

如果目标调用方法带有参数(例如 ThreadPoolTaskExecutor.setMaxPoolSize(int maxPoolSize)),则必须将这些值作为 IntegrationMessageHeaderAccessor.CONTROL_BUS_ARGUMENTS 标头提供:

Message<?> operation =
MessageBuilder.withPayload("myTaskExecutor.setMaxPoolSize")
.setHeader(IntegrationMessageHeaderAccessor.CONTROL_BUS_ARGUMENTS, List.of(10))
.build();
operationChannel.send(operation);

你可以将这些命令视为 JDBC 中带有参数绑定的 PreparedStatement 实例。参数的类型必须与方法参数的类型匹配。它们被用作额外的标准,根据 Java 方法重载特性来选择要调用的方法。例如组件:

@ManagedResource
class TestManagementComponent {

@ManagedOperation
public void operation() {

}

@ManagedOperation(description = "The overloaded operation with int argument")
public void operation(int input) {

}

@ManagedOperation(description = "The overloaded operation with two arguments")
public void operation(int input1, String input2) {

}

@ManagedOperation
public int operation2() {
return 123;
}

}

将暴露 3 个以 operation 命名的命令。当我们调用 testManagementComponent.operation 命令时,需要为 IntegrationMessageHeaderAccessor.CONTROL_BUS_ARGUMENTS 头部选择合适的值列表,以便让 ControlBusCommandRegistry 筛选出 bean 上的目标方法。

使用 Java 注解,你可以按如下方式配置控制总线:

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

类似地,你可以如下配置Java DSL流定义:

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

如果您更倾向于使用自动创建 DirectChannel 的 lambda 表达式,可以按以下方式创建控制总线:

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

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

此外,请参阅控制总线 REST 控制器,了解如何通过 HTTP 公开控制总线管理功能。