您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Model Center   Code  
会员   
   
 
     
   
 订阅
  捐助
针对Java开发者的Apache Camel入门指南
 
  4513  次浏览      16
 2018-1-19
 
编辑推荐:
本文由bigtiger02, jadic翻译,本文将以一个案例,为大家提供一个Java语言(非Groovy)的Apache Camel入门演示。

Apache Camel是一个非常实用的规则引擎库,能够用来处理来自于不同源的事件和信息。你可以在使用不同的协议比如VM,HTTP,FTP,JMS甚至是文件系统中来传递消息,并且让你的操作逻辑和传递逻辑保持分离,这能够让你更专注于消息的内容。

在这篇文章中,我将提供一个Java语言(非Groovy)的Apache Camel入门演示。

首先创建一个Maven项目的pom.xml。

  1. < xml version="1.0" encoding="UTF-8" >
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="
  5. http://maven.apache.org/POM/4.0.0
  6. http://maven.apache.org/maven-v4_0_0.xsd">
  7. <modelVersion>4.0.0</modelVersion>
  8. <groupId>camel-spring-demo</groupId>
  9. <artifactId>camel-spring-demo</artifactId>
  10. <version>1.0-SNAPSHOT</version>
  11. <packaging>jar</packaging>
  12. <properties>
  13. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  14. <camel.version>2.11.1</camel.version>
  15. </properties>
  16. <dependencies>
  17. <dependency>
  18. <groupId>org.apache.camel</groupId>
  19. <artifactId>camel-core</artifactId>
  20. <version>${camel.version}</version>
  21. </dependency>
  22. <dependency>
  23. <groupId>org.slf4j</groupId>
  24. <artifactId>slf4j-simple</artifactId>
  25. <version>1.7.5</version>
  26. </dependency>
  27. </dependencies>
  28. </project>

在这里我们只用到了camel-core.jar包,实际上它提供了许多你可能用到的实用组件。出于日志记录的目的,我使用了slf4j-simple来作为日志记录的实现,从而我们可以从控制台上看到输出。

接下来我们只需要构造一个路由类。路由就好比是Camel中怎样将消息从一端传递到另一端的一个指令定义。我们将会创建src/main/java /camelcoredemo/TimerRouteBuilder.java文件,每隔一秒向处理器发送一个消息,简单打印出来。

  1. package camelcoredemo;
  2. import org.slf4j.*;
  3. import org.apache.camel.*;
  4. import org.apache.camel.builder.*;
  5. public class TimerRouteBuilder extends RouteBuilder {
  6. static Logger LOG = LoggerFactory.getLogger(TimerRouteBuilder.class);
  7. public void configure() {
  8. from("timer://timer1 period=1000")
  9. .process(new Processor() {
  10. public void process(Exchange msg) {
  11. LOG.info("Processing {}", msg);
  12. }
  13. });
  14. }
  15. }

以上就是这个示例的全部所需,现在编译运行。

  1. bash> mvn compile
  2. bash> mvn exec:java -Dexec.mainClass=org.apache.camel.main.Main -Dexec.args='-r camelcoredemo.TimerRouteBuilder'

注意,这里我们并没有编写Java类的main入口,我们只是将RouteBuilder的类名当作参数简单传递给 org.apache.camel.main.Main,然后它将自动加载路由。

控制CamelContext

当启动Camel后,它会创建一个CamelContext对象,该对象拥有了很多关于如何运行Camel的信息,还包含我们所创建的Route的定义。现在如果你想通过CamelContext获得更多的控制,那么你需要编写自己的主类代码。我在这举个简单的例子。

  1. package camelcoredemo;
  2. import org.slf4j.*;
  3. import org.apache.camel.*;
  4. import org.apache.camel.impl.*;
  5. import org.apache.camel.builder.*;
  6. public class TimerMain {
  7. static Logger LOG = LoggerFactory.getLogger(TimerMain.class);
  8. public static void main(String[] args) throws Exception {
  9. new TimerMain().run();
  10. }
  11. void run() throws Exception {
  12. final CamelContext camelContext = new DefaultCamelContext();
  13. camelContext.addRoutes(createRouteBuilder());
  14. camelContext.setTracing(true);
  15. camelContext.start();
  16. Runtime.getRuntime().addShutdownHook(new Thread() {
  17. public void run() {
  18. try {
  19. camelContext.stop();
  20. } catch (Exception e) {
  21. throw new RuntimeException(e);
  22. }
  23. }
  24. });
  25. waitForStop();
  26. }
  27. RouteBuilder createRouteBuilder() {
  28. return new TimerRouteBuilder();
  29. }
  30. void waitForStop() {
  31. while (true) {
  32. try {
  33. Thread.sleep(Long.MAX_VALUE);
  34. } catch (InterruptedException e) {
  35. break;
  36. }
  37. }
  38. }
  39. }

可以看到,我们在createRouteBuilder()方法中重用了已有的TimerRouteBuilder类。现在我们的主类对在什么时候创建、启动、停止CamelContext有了完全的控制。context(camelContext)对象允许你全局性地控制如何配置Camel,而不是在 Route级。它的JavaDoc链接给出了所有setter方法,你可以研究下它都可以做些什么。

注意到一点,我们也需要在我们的主类中提供少量设置代码。首先我们需要处理优雅关闭的问题,所以我们增加了一个Java关闭回调函数去调用context 的stop()方法。其次在context已经启动后,我们需要增加一个线程阻塞。如果在启动后你不阻塞你的主线程,那么它会在启动后就简单的退出了,那就没啥用了。你会把Camel一直作为一个服务(就像一个服务器)运行,直至你按下CTRL+C键去终止该进程。

改善启动CamelContext的主类

如果你不想像上面例子一样过多的处理主类设置代码,那么你可以简单地继承由camel-core提供的 org.apache.camel.main.Main类作为代替。通过利用这个类,你不仅可以让你的context自动设置,还可以获得所有附加的命令行特性,比如控制进程运行多久,启用追踪,加载自定义route类等等。

重构了下上一个例子,代码如下:

  1. package camelcoredemo;
  2. import org.slf4j.*;
  3. import org.apache.camel.builder.*;
  4. import org.apache.camel.main.Main;
  5. public class TimerMain2 extends Main {
  6. static Logger LOG = LoggerFactory.getLogger(TimerMain2.class);
  7. public static void main(String[] args) throws Exception {
  8. TimerMain2 main = new TimerMain2();
  9. main.enableHangupSupport();
  10. main.addRouteBuilder(createRouteBuilder());
  11. main.run(args);
  12. }
  13. static RouteBuilder createRouteBuilder() {
  14. return new TimerRouteBuilder();
  15. }
  16. }

现在TimerMain2类的代码比之前的更少了,你可以试试看,它应该和之前的功能一样。

  1. bash> mvn compile
  2. bash> mvn exec:java -Dexec.mainClass=camelcoredemo.TimerMain2 -Dexec.args='-t'

注意到我们给出-t选项后,会转储Route追踪。使用-h会看到所有可用的选项。

用Camel的注册机制添加bean

在之前的TimerRouteBuilder例子中,我们已经在代码中创建了一个匿名Processor。现在如果你想将几个不同的Processor放在一起,那么使用Camel的注册机制添加bean的方式将能更好的减少代码混乱。Camel允许你通过将processing当作bean注入到它的 registry space,然后你只要把它们当作bean组件来进行调用。如下是我的重构代码:

  1. package camelcoredemo;
  2. import org.slf4j.*;
  3. import org.apache.camel.*;
  4. import org.apache.camel.builder.*;
  5. import org.apache.camel.main.Main;
  6. public class TimerBeansMain extends Main {
  7. static Logger LOG = LoggerFactory.getLogger(TimerBeansMain.class);
  8. public static void main(String[] args) throws Exception {
  9. TimerBeansMain main = new TimerBeansMain();
  10. main.enableHangupSupport();
  11. main.bind("processByBean1", new Bean1());
  12. main.bind("processAgainByBean2", new Bean2());
  13. main.addRouteBuilder(createRouteBuilder());
  14. main.run(args);
  15. }
  16. static RouteBuilder createRouteBuilder() {
  17. return new RouteBuilder() {
  18. public void configure() {
  19. from("timer://timer1 period=1000")
  20. .to("bean:processByBean1")
  21. .to("bean:processAgainByBean2");
  22. }
  23. };
  24. }
  25. // Processor beans
  26. static class Bean1 implements Processor {
  27. public void process(Exchange msg) {
  28. LOG.info("First process {}", msg);
  29. }
  30. }
  31. static class Bean2 implements Processor {
  32. public void process(Exchange msg) {
  33. LOG.info("Second process {}", msg);
  34. }
  35. }
  36. }

现在Route类更简洁明了,同时处理代码也被重构到了独立的类中。当你需要编写很复杂的Route来实现业务逻辑时,这种方式能够帮助你更好的组织和测试你的代码。它能够让你构建像”乐高“积木那样可复用的POJO bean。Camel的registry space同样可用于其他很多用途,比如你可以自定义许多具有附加功能的endpoint组件或者注册一些信息,更或者替换线程池实现策略之内的事情。

上述Route示例是用所谓的Java DSL来构成的,它的可读性较高,你可以用IDE提供的支持查看所有可用于Route的方法。

我希望这篇文章能够帮助你跳过Camel的摸索阶段。除了已经提到的事件组件之外,camel还提供了如下组件:

Have fun!

   
4513 次浏览       16
相关文章

企业架构、TOGAF与ArchiMate概览
架构师之路-如何做好业务建模?
大型网站电商网站架构案例和技术架构的示例
完整的Archimate视点指南(包括示例)
相关文档

数据中台技术架构方法论与实践
适用ArchiMate、EA 和 iSpace进行企业架构建模
Zachman企业架构框架简介
企业架构让SOA落地
相关课程

云平台与微服务架构设计
中台战略、中台建设与数字商业
亿级用户高并发、高可用系统架构
高可用分布式架构设计与实践