此版本仍在开发中,尚未被视为稳定版。如需最新稳定版本,请使用 Spring Integration 7.0.4spring-doc.cadn.net.cn

控制总线

正如《企业集成模式(EIP)一书中所描述的那样,控制总线的理念是:同一消息系统既可用于监控和管理框架内的组件,也可用于“应用级”消息传递。 在 Spring Integration 中,我们基于上述适配器构建功能,使您能够发送消息以调用已暴露的操作。spring-doc.cadn.net.cn

由于控制总线(Control Bus)功能强大,能够修改系统状态,建议对其消息接收进行安全保护(参见SecurityContextChannelInterceptor),并仅将控制总线的管理(消息源)暴露在DMZ区域。

以下示例展示了如何使用 XML 配置控制总线:spring-doc.cadn.net.cn

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

控制总线拥有一个输入通道,可用于调用应用上下文中的 Bean 操作。 它还具备服务激活端点的所有通用属性。 例如,如果操作结果包含需要发送到下游通道的返回值,您可以指定一个输出通道。spring-doc.cadn.net.cn

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

Control Bus 的功能与 JMX 类似,因此命令方法的资格必须遵循以下要求:spring-doc.cadn.net.cn

确保您的自定义方法对控制总线可用的最简单方法是使用 @ManagedAttribute@ManagedOperation 注解。 由于这些注解也用于将方法暴露给 JMX MBean 注册表,因此它们提供了一个便捷的附加好处:通常,您希望暴露给控制总线的相同类型的操作也适合通过 JMX 进行暴露。 有关更多信息,请参阅 ControlBusCommandRegistryControlBusMethodFilter 中的 Javadoc。spring-doc.cadn.net.cn

要在 Spring Bean 上执行方法,客户端可以向操作通道发送消息,如下所示:spring-doc.cadn.net.cn

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

如果目标调用方法具有参数(例如 ThreadPoolTaskExecutor.setMaxPoolSize(int maxPoolSize)),则这些值必须作为 IntegrationMessageHeaderAccessor.CONTROL_BUS_ARGUMENTS 标头提供:spring-doc.cadn.net.cn

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

您可以将这些命令视为带有参数绑定的 PreparedStatement 个 JDBC 实例。 参数的类型必须与方法参数的类型相匹配。 它们用作附加条件,根据 Java 方法重载特性来选择要调用的方法。 例如以下组件:spring-doc.cadn.net.cn

@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 上的目标方法。spring-doc.cadn.net.cn

使用 Java 注解,您可以按如下方式配置控制总线:spring-doc.cadn.net.cn

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

同样,您可以按如下方式配置 Java DSL 流定义:spring-doc.cadn.net.cn

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

如果您更喜欢使用带有自动 DirectChannel 创建的 lambda 表达式,可以按以下方式创建控制总线:spring-doc.cadn.net.cn

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

在这种情况下,通道名称为 controlBus.inputspring-doc.cadn.net.cn

此外,请参见 控制总线 REST 控制器,了解如何通过 HTTP 公开控制总线的管理功能。spring-doc.cadn.net.cn