当前位置: 移动技术网 > IT编程>开发语言>Java > Apache Camel的Java编程入门指南

Apache Camel的Java编程入门指南

2019年07月22日  | 移动技术网IT编程  | 我要评论

 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的摸索阶段。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网