Apache Camel入門教程
本文我們學習Apache Camel,介紹基本概念並重點探討消息路由。從基本概念和術語開始,然後通過介紹兩種方式定義路由————java dsl 和 Spring dsl.
示例主要定義一個路由,實現掃描源文件夾並移動文件至目標文件夾,同時給每個文件名增加時間戳前綴。
1. Apache Camel介紹
Apache Camel是開源集成框架,旨在使集成系統變得簡單和容易。用戶可以使用相同的API集成不同應用系統,支持多種協議和數據類型,允許用戶擴展並引入自定義協議。
1.1. 依賴
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>2.24.2</version>
</dependency>
讀者可以選擇合適版本或最新版本。
1.2. Domain-Specific Language
路由和路由引擎是Camel的核心,路由包括集成不同系統的流程和邏輯。爲了更簡單定義路由,Camel爲不同的語言提供不同的DSL,如Java或Groovy,同時也提供Spring DSL。
大多數用戶傾向於使用Java DSL 和Spring DSL,兩者都提供大多數功能。Java DSL提供了一些Spring DSL不支持的特性,然而Spring DSL有時更有益,因爲XML可以在不需要重新編譯代碼的情況下進行更改。
1.3. 術語和架構
下面說下Camel中解綁的術語和架構。首先看一些核心概念:
-
消息(Message) 包含傳輸給路由的數據。每個消息有唯一標識,它由消息體、消息頭及附件組成。
-
交換(Exchange) 是消息的容器,它是在路由過程中消費者接收到消息時創建的。Exchange允許不同類型的系統間交互————它可以定義單向消息或請求-響應消息
-
端點(Endpoint) 是系統接收或發送消息的通道。可以引用web服務URI, 隊列 URI, 文件,email地址等。
-
組件(Component) 可以理解爲端點工廠。簡言之,組件提供不同技術使用相關方法和語法的接口。Camel 已經提供很多DSL表示的組件,幾乎包括大多數可能的技術,並提供自定義組件的能力。
-
處理器(Processor) 是給路由增加自定義集成邏輯的Java接口。包括單個處理方法用於在消費者接收消息時執行自義定業務邏輯。
在高層次上看Camel的架構非常簡單。CamelContext表示Camel運行時系統,它連接不同的概念,如路由、組件或端點。在此之下,處理器處理端點之間的路由和交換,而端點則集成不同的系統。
2. 定義路由
路由可以使用Java dsl或Spring dsl進行定義。下面分別使用兩種方式進行定義,實現移動文件功能。
2.1. Java DSL
使用Java Dsl定義路由,首先需要創建CamelContext,然後需擴展RouteBuilder並實現其configure方法,其中包括路由流程:
private static final long DURATION_MILIS = 10000;
private static final String SOURCE_FOLDER = "src/test/source-folder";
private static final String DESTINATION_FOLDER
= "src/test/destination-folder";
@Test
public void moveFolderContentJavaDSLTest() throws Exception {
CamelContext camelContext = new DefaultCamelContext();
camelContext.addRoutes(new RouteBuilder() {
@Override
public void configure() throws Exception {
from("file://" + SOURCE_FOLDER + "?delete=true").process(
new FileProcessor()).to("file://" + DESTINATION_FOLDER);
}
});
camelContext.start();
Thread.sleep(DURATION_MILIS);
camelContext.stop();
}
configure方法邏輯爲:從源文件夾讀文件,使用FileProcessor處理文件,然後發送結果值目標文件夾。delete=true
是設置處理完成後刪除源文件夾內容。
要啓動Camel,需調用CamelContext的start方法。執行Thread.sleep方法是爲了給Camel必要的時間移動文件。
FileProcessor 實現 Processor 接口,包括單個process方法進行修改文件名稱的處理邏輯:
public class FileProcessor implements Processor {
public void process(Exchange exchange) throws Exception {
String originalFileName = (String) exchange.getIn().getHeader(
Exchange.FILE_NAME, String.class);
Date date = new Date();
SimpleDateFormat dateFormat = new SimpleDateFormat(
"yyyy-MM-dd HH-mm-ss");
String changedFileName = dateFormat.format(date) + originalFileName;
exchange.getIn().setHeader(Exchange.FILE_NAME, changedFileName);
}
}
爲了獲取文件名,我們需要從交換中接收報文並獲取消息頭信息,接着修改文件名也是修改消息頭信息。
2.2. Spring DSL
下面通過Spring DSL定義路由。我們使用xml文件設置路由和處理器,對象有Spring進行控制反轉,當然也可以使用Java config方式進行配置。
實現功能與上節示例一致,因此這裏主要聚集Spring dsl的配置。CamelContext也在配置中進行實例化,但路由使用Java dsl進行配置:
<bean id="fileRouter" class="org.baeldung.camel.file.FileRouter" />
<bean id="fileProcessor" class="org.baeldung.camel.file.FileProcessor" />
<camelContext xmlns="http://camel.apache.org/schema/spring">
<routeBuilder ref="fileRouter" />
</camelContext>
這種方式告訴Camel使用FileRouter類配置路由:
public class FileRouter extends RouteBuilder {
private static final String SOURCE_FOLDER =
"src/test/source-folder";
private static final String DESTINATION_FOLDER =
"src/test/destination-folder";
@Override
public void configure() throws Exception {
from("file://" + SOURCE_FOLDER + "?delete=true").process(
new FileProcessor()).to("file://" + DESTINATION_FOLDER);
}
}
下面進行測試,我們需要創建ClassPathXmlApplicationContext實例,載入Camel的Spring配置文件:
@Test
public void moveFolderContentSpringDSLTest() throws InterruptedException {
ClassPathXmlApplicationContext applicationContext =
new ClassPathXmlApplicationContext("camel-context.xml");
Thread.sleep(DURATION_MILIS);
applicationContext.close();
}
通過使用這種方法,我們既利用Spring的靈活性和好處,又使用Java DSL實現的所有可能特性。
3. 總結
本文我們介紹了Apache Camel並演示瞭如何使用Camel進行集成任務。示例中Camel讓您專注於業務邏輯,無需寫過多的模板代碼。