Bootiful Spring Boot 3.4:Spring Integration

工程 | Josh Long | 2024 年 11 月 24 日 | ...

Spring Integration 6.4 是您處理所有企業應用程式整合問題的一站式商店。 它支援眾多的訊息傳遞和整合模式,甚至更多用於各種技術的介面卡——SFTP、FTP、Redis、Apache Pulsar、Apache Kafka、JDBC、TCP/IP 等。 因此,正如您可能已經猜到的那樣,根本無法跟上它們。發行說明做得非常好,因此我將列出我的一些最愛。

  • 遠端檔案系統入站介面卡現在使用 clearFetchedCache() 方法從快取中刪除未處理的遠端檔案的引用。
  • Spring Integration 分散式鎖機制有一個方法 - LockRepository#delete - 現在返回刪除分散式鎖所有權的結果。
  • 類似地,分散式鎖的 Redis 支援實現 - RedisLockRegistry - 如果鎖的所有權已過期,則丟擲 ConcurrentModificationException
  • 現在有一個方便的 Consumer<SshClient> 允許進一步自定義內部 SshClient
  • 出站 ZeroMQ 現在可以繫結到 TCP 埠,而不是連線到 URL。
  • 現在可以使用相應的 ClientManager 透過 IntegrationFlowContext 在執行時新增 MqttPahoMessageDrivenChannelAdapterMqttv5PahoMessageDrivenChannelAdapter 的多個例項。
  • 對 Python 的指令碼支援現在建立在 GraalVM Truffle Polyglot 實現之上
  • AbstractMailReceiver 公開了一個選項來停用設定 Flags.Flag.FLAGGED
  • MessageBuilder 中提取了一個新的 BaseMessageBuilder,以簡化構建自定義構建器實現,其中大多數邏輯應與 `MessageBuilder 的邏輯相同。
  • 有一個新的 ControlBusFactoryBean 可以簡化新建 ControlBus 的過程。 此外,還有一個新的 Control Bus HTTP 控制器。

我認為改進的控制匯流排支援非常值得關注! 控制匯流排模式背後的想法是,應該可以使用與用於向系統傳送訊息相同的帶內訊息傳遞基礎設施來控制系統。 使用 Spring Integration 控制 Spring Integration(和您的 Spring 應用程式)。 Spring 有一種機制可以自動檢測並公開使用 @ManagedResource 註釋的 Spring bean 作為 JMX bean 進行操作。 Spring Integration 中的 ControlBus 機制採用相同的 bean 並匯出它們,以便透過傳入和傳出 Spring Integration 的訊息進行操作。

package com.example.bootiful_34.integration;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.dsl.DirectChannelSpec;
import org.springframework.integration.dsl.IntegrationFlow;
import org.springframework.integration.dsl.MessageChannels;
import org.springframework.integration.http.config.EnableControlBusController;
import org.springframework.jmx.export.annotation.ManagedOperation;
import org.springframework.jmx.export.annotation.ManagedResource;
import org.springframework.messaging.MessageChannel;

import java.util.concurrent.atomic.AtomicInteger;

@Configuration
@EnableControlBusController
class ControlBusConfiguration {

	@Bean
	IntegrationFlow controlBusFlow(MessageChannel controlBusFlowMessageChannel) {
		return IntegrationFlow.from(controlBusFlowMessageChannel).controlBusOnRegistry().get();
	}

	@Bean
	DirectChannelSpec controlBusFlowMessageChannel() {
		return MessageChannels.direct();
	}

	@Bean
	MyOperationsManagedResource myOperationsManagedResource() {
		return new MyOperationsManagedResource();
	}

	@ManagedResource
	public static class MyOperationsManagedResource {

		static final AtomicInteger COUNTER = new AtomicInteger(0);

		@ManagedOperation(description = "Update the magic number")
		public void updateMagicNumber(int magicNumber) {
			System.out.println("doSomething with magic number " + magicNumber);
			COUNTER.incrementAndGet();
		}

	}

}

在此示例中,一個 bean 操作一些重要的狀態——配置一些神奇的數字。 好的,好的,我明白為什麼這不是最誘人的示例。 但請耐心等待。 無論如何,它提供了一個方法——updateMagicNumber(int)——我們希望可以透過 JMX 和 Spring Integration 的 ControlBus 訪問它。 我正常註冊 bean,確保也使用 @ManagedResource 註釋該類。

我定義了一個型別為 DirectChannel 的 Spring MessageChannel,然後定義了一個 Spring Integration IntegrationFlow,它透過 DirectChannel 將所有訊息路由到 Spring 應用程式中的控制匯流排。 然後,控制匯流排將調整訊息並將其路由到適當的託管資源。 讓我們看看訊息需要是什麼樣子才能呼叫該託管資源及其期望引數的方法。

package com.example.bootiful_34.integration;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.integration.IntegrationMessageHeaderAccessor;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.support.MessageBuilder;

import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;

@SpringBootTest
class ControlBusConfigurationTest {

	@Test
	void controlBusConfigurationRunner(@Autowired MessageChannel controlBusFlowMessageChannel) {
		var msg = MessageBuilder.withPayload("myOperationsManagedResource.updateMagicNumber")
			.setHeaderIfAbsent(IntegrationMessageHeaderAccessor.CONTROL_BUS_ARGUMENTS, List.of(42))
			.build();
		assertEquals(ControlBusConfiguration.MyOperationsManagedResource.COUNTER.get(), 0,
				"there should be zero invocations of the control bus thus far");
		controlBusFlowMessageChannel.send(msg);
		assertEquals(ControlBusConfiguration.MyOperationsManagedResource.COUNTER.get(), 1,
				"there should be one invocation of the control bus thus far");
	}

}

確實足夠簡單了? 在此測試中,我們注入 DirectChannel 並建立一個新的 Message,其有效負載是託管資源 bean 的名稱以及該託管資源上的方法,以及一些資料傳遞到該託管資源 bean 的方法的引數中。 測試的其餘部分只是為了確保訊息已成功傳遞,並且計數器已遞增以反映呼叫。

ControlBus 模式非常強大! 請記住:Spring MessageChannel 例項是您連線到任何其他系統的閘道器,無論是透過 Spring Cloud Stream、Spring Framework 4 的 WebSocket 支援還是 Spring Integration 的入站介面卡。 此方法呼叫可能同樣快速地由檔案存放在 FTP 伺服器上、Apache Kafka 佇列上到達的新訊息或特定部分到達的 TCP 有效負載導致。 我們可以使用 Spring Security 來保護入站訊息通道,拒絕無法進行身份驗證的訊息。 這比直接使用 JMX 容易得多。

如果這還不夠,新的 @EnableControlBusController 註釋會公開匯出 ControlBus 功能!

獲取 Spring 新聞通訊

透過 Spring 新聞通訊保持聯絡

訂閱

領先一步

VMware 提供培訓和認證來加速您的進步。

瞭解更多

獲得支援

Tanzu Spring 在一個簡單的訂閱中提供對 OpenJDK™、Spring 和 Apache Tomcat® 的支援和二進位制檔案。

瞭解更多

即將舉行的活動

檢視 Spring 社群中所有即將舉行的活動。

檢視全部