Apache Camel 支援
Spring Integration 提供了一套 API 和配置,用於與在同一應用程式上下文中宣告的 Apache Camel 端點進行通訊。
專案需要此依賴項
-
Maven
-
Gradle
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-camel</artifactId>
<version>7.0.0</version>
</dependency>
compile "org.springframework.integration:spring-integration-camel:7.0.0"
Spring Integration 和 Apache Camel 都實現了企業整合模式,並提供了方便的方式來組合它們,但這兩個專案在 API 和抽象實現上採用了不同的方法。Spring Integration 完全依賴於 Spring Core 的依賴注入容器。它利用許多其他 Spring 專案(Spring Data、Spring AMQP、Spring for Apache Kafka 等)來實現其通道介面卡。它還將 MessageChannel 抽象作為一流公民,開發者在組合其整合流時需要了解這一點。另一方面,Apache Camel 不提供訊息通道的一流公民抽象,而是透過對 API 隱藏的內部交換來組合其路由。此外,它需要一些額外的依賴和配置才能在 Spring 應用程式中使用。
即使對於最終的企業整合解決方案而言,其各部分的實現方式並不重要,但開發者體驗和高生產力是需要考慮的因素。因此,開發者可能出於多種原因選擇一個框架而非另一個,或者在某些目標系統支援存在差距時同時選擇兩者。Spring Integration 和 Apache Camel 應用程式可以透過許多外部協議相互互動,它們都為這些協議實現了通道介面卡。例如,Spring Integration 流可以向 Apache Kafka 主題釋出一條記錄,該記錄由消費端的 Apache Camel 端點消費。或者,Apache Camel 路由可以將資料寫入 SFTP 檔案到目錄中,該目錄由 Spring Integration 的 SFTP 入站通道介面卡輪詢。或者,在同一個 Spring 應用程式上下文中,它們可以透過 ApplicationEvent 進行通訊。
Apache Camel 出站通道介面卡
CamelMessageHandler 是 AbstractReplyProducingMessageHandler 的實現,可以以單向(預設)和請求-回覆兩種模式工作。它使用 org.apache.camel.ProducerTemplate 向 org.apache.camel.Endpoint 傳送(或傳送和接收)訊息。互動模式可以透過 ExchangePattern 選項控制(該選項可以在執行時透過 SpEL 表示式根據請求訊息進行評估)。目標 Apache Camel 端點可以明確配置,也可以配置為在執行時評估的 SpEL 表示式。否則,它將回退到 ProducerTemplate 上提供的 defaultEndpoint。除了指定端點,還可以提供內聯的、顯式的 LambdaRouteBuilder,例如,用於呼叫 Spring Integration 中沒有通道介面卡支援的 Apache Camel 元件。
此外,可以提供一個 HeaderMapper<org.apache.camel.Message>(CamelHeaderMapper 是預設實現),以確定在 Spring Integration 和 Apache Camel 訊息之間對映哪些頭。預設情況下,所有頭都被對映。
CamelMessageHandler 支援 async 模式,呼叫 ProducerTemplate.asyncSend() 並生成一個 CompletableFuture 用於回覆處理(如果有的話)。
exchangeProperties 可以透過 SpEL 表示式進行自定義,該表示式必須評估為一個 Map。
如果未提供 ProducerTemplate,則透過從應用程式上下文中解析的 CamelContext Bean 建立一個。
@Bean
@ServiceActivator(inputChannel = "sendToCamel")
CamelMessageHandler camelService(ProducerTemplate producerTemplate) {
CamelHeaderMapper headerMapper = new CamelHeaderMapper();
headerMapper.setOutboundHeaderNames("");
headerMapper.setInboundHeaderNames("testHeader");
CamelMessageHandler camelMessageHandler = new CamelMessageHandler(producerTemplate);
camelMessageHandler.setEndpointUri("direct:simple");
camelMessageHandler.setExchangePatternExpression(spelExpressionParser.parseExpression("headers.exchangePattern"));
camelMessageHandler.setHeaderMapper(headerMapper);
return camelMessageHandler;
}
對於 Java DSL 流定義,此通道介面卡可以透過 Camel 工廠提供的幾種變體進行配置。
@Bean
IntegrationFlow camelFlow() {
return f -> f
.handle(Camel.gateway().endpointUri("direct:simple"))
.handle(Camel.route(this::camelRoute))
.handle(Camel.handler().endpointUri("log:com.mycompany.order?level=WARN"));
}
private void camelRoute(RouteBuilder routeBuilder) {
routeBuilder.from("direct:inbound").transform(routeBuilder.simple("${body.toUpperCase()}"));
}