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的摸索阶段。
推荐阅读
-
Apache Camel的Java编程入门指南
-
Java网络编程从入门到精通(19):套接字(Socket)的异常
-
为什么在美国的cs编程入门课大多有java和python。而在国内首先学习的语言是c/c++?
-
java计算机编程入门教程(免费的编程自学网站)
-
java从入门到精通哪个版本好(免费的编程自学网站)
-
java计算机编程入门教程(免费的编程自学网站)
-
Python的设计模式编程入门指南
-
java从入门到精通哪个版本好(免费的编程自学网站)
-
编程初学者入门7_公务员面试现场打分。有7位考官,从键盘输入若干组成绩,每组7个分数(百分制),去掉一个最高分和一个最低分,输出每组的平均成绩。(复习冒泡排序+C、Java中局部变量不赋值不能使用))
-
关于 HSSF 和 XSSF 功能的开发者入门指南 (Apache POI 操作 Excel)