Apache Camel的Java编程入门指南

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

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

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

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">

<modelVersion>4.0.0</modelVersion>
<groupId>camel-spring-demo</groupId>
<artifactId>camel-spring-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<camel.version>2.11.1</camel.version>
</properties>

<dependencies>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.5</version>
</dependency>
</dependencies>

</project>

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

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

package camelcoredemo;

import org.slf4j.*;
import org.apache.camel.*;
import org.apache.camel.builder.*;

public class TimerRouteBuilder extends RouteBuilder {
static Logger LOG = LoggerFactory.getLogger(TimerRouteBuilder.class);
public void configure() {
from("timer://timer1?period=1000")
.process(new Processor() {
public void process(Exchange msg) {
LOG.info("Processing {}", msg);
}
});
}
}

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

bash> mvn compile
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获得更多的控制,那么你需要编写自己的主类代码。我在这举个简单的例子。

package camelcoredemo;

import org.slf4j.*;
import org.apache.camel.*;
import org.apache.camel.impl.*;
import org.apache.camel.builder.*;

public class TimerMain {
static Logger LOG = LoggerFactory.getLogger(TimerMain.class);
public static void main(String[] args) throws Exception {
new TimerMain().run();
}
void run() throws Exception {
final CamelContext camelContext = new DefaultCamelContext();
camelContext.addRoutes(createRouteBuilder());
camelContext.setTracing(true);
camelContext.start();

Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
try {
camelContext.stop();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
});

waitForStop();
}
RouteBuilder createRouteBuilder() {
return new TimerRouteBuilder();
}
void waitForStop() {
while (true) {
try {
Thread.sleep(Long.MAX_VALUE);
} catch (InterruptedException e) {
break;
}
}
}
}

可以看到,我们在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类等等。

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

package camelcoredemo;

import org.slf4j.*;
import org.apache.camel.builder.*;
import org.apache.camel.main.Main;

public class TimerMain2 extends Main {
static Logger LOG = LoggerFactory.getLogger(TimerMain2.class);
public static void main(String[] args) throws Exception {
TimerMain2 main = new TimerMain2();
main.enableHangupSupport();
main.addRouteBuilder(createRouteBuilder());
main.run(args);
}
static RouteBuilder createRouteBuilder() {
return new TimerRouteBuilder();
}
}

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

bash> mvn compile
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组件来进行调用。如下是我的重构代码:

package camelcoredemo;

import org.slf4j.*;
import org.apache.camel.*;
import org.apache.camel.builder.*;
import org.apache.camel.main.Main;

public class TimerBeansMain extends Main {
static Logger LOG = LoggerFactory.getLogger(TimerBeansMain.class);
public static void main(String[] args) throws Exception {
TimerBeansMain main = new TimerBeansMain();
main.enableHangupSupport();
main.bind("processByBean1", new Bean1());
main.bind("processAgainByBean2", new Bean2());
main.addRouteBuilder(createRouteBuilder());
main.run(args);
}
static RouteBuilder createRouteBuilder() {
return new RouteBuilder() {
public void configure() {
from("timer://timer1?period=1000")
.to("bean:processByBean1")
.to("bean:processAgainByBean2");
}
};
}

// Processor beans
static class Bean1 implements Processor {
public void process(Exchange msg) {
LOG.info("First process {}", msg);
}
}
static class Bean2 implements Processor {
public void process(Exchange msg) {
LOG.info("Second process {}", msg);
}
}
}

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

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

我希望这篇文章能够帮助你跳过Camel的摸索阶段。

(0)

相关推荐

  • Apache Camel的Java编程入门指南

    Apache Camel是一个非常实用的规则引擎库,能够用来处理来自于不同源的事件和信息.你可以在使用不同的协议比如VM,HTTP,FTP,JMS甚至是文件系统中来传递消息,并且让你的操作逻辑和传递逻辑保持分离,这能够让你更专注于消息的内容. 在这篇文章中,我将提供一个Java语言(非Groovy)的Apache Camel入门演示. 首先创建一个Maven项目的pom.xml. <?xml version="1.0" encoding="UTF-8"?>

  • java swing编程入门代码编写(java编程入门)

    Swing编程基本流程 第一步: 取得主窗体 复制代码 代码如下: JFrame jf = new JFrame("Demo1"); 第二步:获得主窗体的容器 复制代码 代码如下: Container c = jf.getContentPane(); 第三步:设置容器布局 复制代码 代码如下: c.setLayout(new FlowLayout(FlowLayout.LEFT,20,20)); 第四步:添加组件及设置组件属性 复制代码 代码如下: JLabel label1 = ne

  • Python编程入门指南之函数

    目录 Python编程:函数 定义和调用函数 向函数传递信息 传递实参:位置实参 传递实参:关键字实参 传递实参:默认值 传递列表 禁止函数修改列表 传递任意数量实参 返回值 返回简单值 让实参可选 返回字典 将函数存储在模块中 导入整个模块 导入特定函数 使用as给函数指定别名 使用as给模块指定别名 导入模块中的所有函数 函数编写指南 总结 Python编程:函数 函数是带名字的代码块,用于完成具体的工作.要执行函数定义的特定任务,可调用该函数.需要在程序中多次执行同一项任务时,你无需反复编

  • Python的设计模式编程入门指南

    有没有想过设计模式到底是什么?通过本文可以看到设计模式为什么这么重要,通过几个Python的示例展示为什么需要设计模式,以及如何使用. 设计模式是什么? 设计模式是经过总结.优化的,对我们经常会碰到的一些编程问题的可重用解决方案.一个设计模式并不像一个类或一个库那样能够直接作用于我们的代码.反之,设计模式更为高级,它是一种必须在特定情形下实现的一种方法模板.设计模式不会绑定具体的编程语言.一个好的设计模式应该能够用大部分编程语言实现(如果做不到全部的话,具体取决于语言特性).最为重要的是,设计模

  • java编程SpringSecurity入门原理及应用简介

    目录 1. SpringSecurity 框架简介 1.1 概要 1.2 组成以及同款产品(shiro)对比 1.2.1 Spring Security 1.2.2 Shiro 1.3 模块划分 1.4 SpringSecurity 基本原理 1.5.UserDetailsService 接口讲解 2.SpringSecurity Web 权限方案 2.1设置登录系统的账号密码(三种方式) 设计数据库表 建立springboot项目,勾选相应依赖 完整pom.xml 数据库配置 创建对应的实体类

  • ColdFusionMX 编程指南 ColdFusionMX编程入门

    第三期:ColdFusionMX编程入门 序言 上一期我们讲解了ColdFusionMX的基本管理操作,并且熟悉了ColdFusionMX的管理界面布局,而且上一期最后我们演示了两个非常短小的coldfusion程序,这一期会详细讲解coldfusion的入门编程,其中包括在asp中对于初学者而言非常令人头疼的数据库操作. 在每次开始进入正题之前,每一期的序言内容都会为大家介绍一些关于ColdFusion发展或者其他一些具有价值的小知识,第一期为大家介绍了Macromedia MX产品的策略和c

  • java的if else语句入门指南(推荐)

    条件语句,是程序中根据条件是否成立进行选择执行的一类语句,这类语句在实际使用中,难点在于如何准确的抽象条件.例如实现程序登录功能时,如果用户名和密码正确,则进入系统,否则弹出"密码错误"这样的提示框等. 本部分对于条件语句的介绍,重点在于语法讲解和基本的使用,更详细的使用参看后续的综合示例部分. 在Java语言中,条件语句主要有两类语法:if语句和switch语句. 1 .if语句 if关键字中文意思是如果,其细致的语法归纳来说总共有三种:if语句.if-else语句和if-else

  • Java编程反射机制用法入门与实例总结

    本文实例讲述了Java编程反射机制用法.分享给大家供大家参考,具体如下: 前言:反射:动态获取类 (字节码文件 如本篇中的Person.class),并对其成员进行运行.反射在Android应用层的开发中可能遇到会稍微少一点,但对于想打通底层的小伙伴来说,必须要熟练掌握运用. 实体类 Person.java package com.sunwenou.reflect;// 包名 public class Person { private String name; private int age;

  • 从0开始学习大数据之java spark编程入门与项目实践

    本文实例讲述了大数据java spark编程.分享给大家供大家参考,具体如下: 上节搭建好了eclipse spark编程环境 在测试运行scala 或java 编写spark程序 ,在eclipse平台都可以运行,但打包导出jar,提交 spark-submit运行,都不能执行,最后确定是版本问题,就是你在eclipse调试的spark版本需和spark-submit 提交spark的运行版本一致,还有就是scala版本一致,才能正常运行. 以下是java spark程序运行 1.新建mave

  • java开发AOP面向切面编程入门

    目录 引言 不好的解决方案 面向过程的解决方案 使用继承解决方案 使用聚合的解决方案 面向切面的编程基本概念 基于Spring面向切面程序实现 小结 引言 在实际应用场景中,我们封装一个学生的类,这个类用于封装学生的日常行为,如:上学.吃饭.上课等.然而,在疫情期间,学生上学时入校.吃饭时进入餐厅,需要测温查验证件等行为,拿到这样的需求我们怎么办? 不好的解决方案 面向过程的解决方案 遇到问题解决问题,在上学.吃饭方法中加上测温.查验证件方法,或者在学生类中提炼一个测温查验证件私有的方法,在需要

随机推荐