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让您专注于业务逻辑,无需写过多的模板代码。