|
如需使用最新稳定版本,请使用 Spring Integration 7.0.4! |
控制总线
正如《企业集成模式(EIP)一书中所描述的那样,控制总线的理念是:同一消息系统既可用于监控和管理框架内的组件,也可用于“应用级”消息传递。 在 Spring Integration 中,我们基于上述适配器构建功能,使您能够发送消息以调用已暴露的操作。
由于控制总线(Control Bus)功能强大,能够修改系统状态,建议对其消息接收进行安全保护(参见SecurityContextChannelInterceptor),并仅将控制总线的管理(消息源)暴露在DMZ区域。 |
以下示例展示了如何使用 XML 配置控制总线:
<int:control-bus input-channel="operationChannel"/>
控制总线拥有一个输入通道,可用于调用应用上下文中的 Bean 操作。 它还具备服务激活端点的所有通用属性。 例如,如果操作结果包含需要发送到下游通道的返回值,您可以指定一个输出通道。
控制总线在输入通道上以简单的字符串格式(如beanName.methodName)运行消息作为托管操作。
目标方法参数的参数必须作为列表提供在IntegrationMessageHeaderAccessor.CONTROL_BUS_ARGUMENTS标头中。
要调用的 Bean 和方法从ControlBusCommandRegistry基础设施 Bean 中解析得出。
默认情况下,ControlBusCommandRegistry按需注册命令:其eagerInitialization标志可通过@EnableIntegrationManagement(loadControlBusCommands = "true")开启。
Control Bus 的功能与 JMX 类似,因此命令方法的资格必须遵循以下要求:
-
已使用
@ManagedAttribute或@ManagedOperation注解的方法; -
Spring 的
Lifecycle接口(以及自 5.2 版本起其Pausable扩展); -
用于配置 Spring 的
TaskExecutor和TaskScheduler实现的若干方法。
确保您的自定义方法对控制总线可用的最简单方法是使用 @ManagedAttribute 或 @ManagedOperation 注解。
由于这些注解也用于将方法暴露给 JMX MBean 注册表,因此它们提供了一个便捷的附加好处:通常,您希望暴露给控制总线的相同类型的操作也适合通过 JMX 进行暴露。
有关更多信息,请参阅 ControlBusCommandRegistry 和 ControlBusMethodFilter 中的 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);
您可以将这些命令视为带有参数绑定的 PreparedStatement 个 JDBC 实例。
参数的类型必须与方法参数的类型相匹配。
它们用作附加条件,根据 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 公开控制总线的管理功能。