长沙分类信息网-长沙新闻网

规则引擎 Apache Camel

2024-7-4 14:07:57发布次查看发布人:
apache camel是一个非常实用的规则引擎库,能够用来处理来自于不同源的事件和信息。你可以在使用不同的协议比如vm,.org/2001/xmlschema-instance
xsi:schemalocation=
.0.0
_0_0.xsd>
4.0.0
camel-spring-demo
camel-spring-demo
1.0-snapshot
jar
utf-8
2.11.1
org.apache.camel
camel-core
${camel.version}
org.slf4j
slf4j-simple
1.7.5
在这里我们只用到了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://timer1period=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://timer1period=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的方法。

该用户其它信息

推荐信息

长沙分类信息网-长沙新闻网
关于本站