1. 概述
本文將演示如何配置和使用 Apache Camel 與 Spring 的集成。
Apache Camel 提供了大量的實用組件,支持諸如 JPA、Hibernate、FTP、Apache-CXF、AWS-S3 以及眾多其他組件——所有這些旨在幫助在兩個不同系統之間集成數據。
例如,使用 Hibernate 和 Apache CXF 組件,您可以從數據庫中拉取數據並將其發送到另一個系統,通過 REST API 調用。
在本教程中,我們將探討一個簡單的 Camel 示例——讀取文件並將其內容轉換為大寫,然後再轉換為小寫。 我們將使用 Camel 的 File 組件 和 Spring 4.2。
以下是該示例的詳細信息:
- 從源目錄讀取文件
- 使用自定義 Processor 將文件內容轉換為大寫
- 將轉換後的輸出寫入目標目錄
- 使用 Camel Translator 將文件內容轉換為小寫
- 將轉換後的輸出寫入目標目錄
2. 添加依賴
要使用 Apache Camel 與 Spring 結合使用,您需要在 POM 文件中添加以下依賴項:
<properties>
<camel.version>4.3.0</camel.version>
<spring.version>5.3.25</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-spring</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-stream</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>因此,我們有:
- camel-core – Apache Camel 的主要依賴項
- camel-spring – 允許我們使用 Camel 與 Spring
- camel-stream – 一個可選依賴項,你可以使用(例如)在路由運行時在控制枱中顯示一些消息
- spring-context – 標準 Spring 依賴項,由於我們將要在 Spring 上下文中運行 Camel 路由,因此在本例中是必需的
3. Spring Camel Context
首先,我們將創建 Spring Config 文件,其中我們將定義 Camel 路由。
請注意,該文件包含所有必需的 Apache Camel 和 Spring 命名空間以及模式位置。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:camel="http://camel.apache.org/schema/spring"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://camel.apache.org/schema/spring
http://camel.apache.org/schema/spring/camel-spring.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-4.2.xsd">
<camelContext xmlns="http://camel.apache.org/schema/spring">
<!-- Add routes here -->
</camelContext>
</beans><camelContext> 元素代表( unsurprisingly) Camel 上下文,可以將其與 Spring 應用上下文進行比較。 您的上下文文件現在已準備好開始定義 Camel 路由。
3.1. 使用自定義處理器 Camel 路由
接下來,我們將編寫我們的第一個路由,將文件內容轉換為大寫。
我們需要定義路由從中讀取數據的源。這個源可以是數據庫、文件、控制枱,或者其他各種源。在本例中,我們將使用文件。
然後,我們需要定義從源讀取的數據的處理器。對於本例,我們將編寫一個自定義處理器類。這個類將是一個 Spring Bean,它將實現標準的 Camel Processor 接口。
一旦數據被處理,我們需要告訴路由將處理後的數據發送到哪裏。 同樣,這可以是一個廣泛的各種輸出,例如數據庫、文件或控制枱。在本例中,我們將將其存儲在文件中。
為了設置這些步驟,包括輸入、處理器和輸出,請將以下路由添加到 Camel 上下文文件中:
<route>
<from uri="file://data/input" /> <!-- INPUT -->
<process ref="myFileProcessor" /> <!-- PROCESS -->
<to uri="file://data/outputUpperCase" /> <!-- OUTPUT -->
</route>此外,我們還需要定義 myFileProcessor Bean:
<bean id="myFileProcessor" class="org.apache.camel.processor.FileProcessor" />3.2. 自定義大寫處理器
現在我們需要創建我們在 Bean 中定義的自定義文件處理器。它必須實現 Camel 的 Processor 接口,定義一個名為 process 的單方法,該方法接受一個 Exchange 對象作為輸入。該對象提供輸入源數據的詳細信息。
該方法必須從 Exchange 對象中讀取消息,將內容轉換為大寫,然後將新內容設置回 Exchange 對象中:
public class FileProcessor implements Processor {
public void process(Exchange exchange) throws Exception {
String originalFileContent = (String) exchange.getIn().getBody(String.class);
String upperCaseFileContent = originalFileContent.toUpperCase();
exchange.getIn().setBody(upperCaseFileContent);
}
}此過程方法將針對來自源頭的每個輸入執行。
3.3. 轉換為小寫的處理器
現在我們將添加另一個輸出到 Camel 路由中。這次,我們將把相同輸入文件的數據轉換為小寫。這次我們不會使用自定義處理器,而是將使用 Apache Camel 的 消息翻譯器 功能。這是更新後的 Camel 路由:
<route>
<from uri="file://data/input" />
<process ref="myFileProcessor" />
<to uri="file://data/outputUppperCase" />
<transform>
<simple>${body.toLowerCase()}</simple>
</transform>
<to uri="file://data/outputLowerCase" />
</route>4. 運行應用程序
為了使我們的路由生效,我們只需要將 Camel 上下文文件加載到 Spring 應用上下文之中:
ClassPathXmlApplicationContext applicationContext =
new ClassPathXmlApplicationContext("camel-context.xml");
路線運行成功後,將會創建兩個文件:一個包含大寫內容,另一個包含小寫內容。
5. 結論
如果您正在進行集成工作,Apache Camel 肯定會使事情變得更容易。該庫提供了可插拔式組件,將幫助您減少樣板代碼,並專注於處理數據的核心邏輯。
如果您想詳細瞭解 企業集成模式 概念,則應查看 這本書,由格雷戈裏·霍普和鮑比·伍爾夫撰寫,他們非常清晰地概念化了 EIP。