控制匯流排
正如《企業整合模式》(EIP) 一書中所述,控制匯流排背後的理念是,用於監控和管理框架內元件的訊息系統與用於“應用級別”訊息傳遞的系統是相同的。在 Spring Integration 中,我們基於上述介面卡進行構建,這樣你就可以透過傳送訊息來呼叫暴露的操作。
由於控制匯流排足以更改系統狀態,因此建議保護其訊息接收(參見 SecurityContextChannelInterceptor),並且僅在 DMZ 中公開控制匯流排管理(訊息源)。 |
以下示例展示瞭如何使用 XML 配置控制匯流排
<int:control-bus input-channel="operationChannel"/>
控制匯流排有一個輸入通道,可以用來呼叫應用程式上下文中 bean 的操作。它還具有服務啟用端點的所有常見屬性。例如,如果操作結果有返回值,並且您希望將其傳送到下游通道,則可以指定一個輸出通道。
控制匯流排以 beanName.methodName 這樣的簡單字串格式在輸入通道上執行訊息作為託管操作。目標方法引數的引數必須作為列表在 IntegrationMessageHeaderAccessor.CONTROL_BUS_ARGUMENTS 頭部中提供。要呼叫的 bean 和方法從 ControlBusCommandRegistry 基礎設施 bean 解析。預設情況下,ControlBusCommandRegistry 按需註冊命令:其 eagerInitialization 標誌可以透過 @EnableIntegrationManagement(loadControlBusCommands = "true") 開啟。
控制匯流排的功能類似於 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);
您可以將這些命令視為 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 暴露控制匯流排管理。