规则引擎(Apache camel) 学习六
1.处理Dynamic Recipient List
介绍:在编排路由,很多情况下开发人员不能确定有哪些接收者会成为下一个处理元素:
因为它们需要由Exchange中所携带的消息内容来动态决定下一个处理元素。
这种情况下,开发人员就需要用到recipient方法对下一路由目标进行动态判断。
示例:
以下代码示例中,我们将三个已经编排好的路由注册到Camel服务中,并通过打印在控制台上的结果观察其执行:
第一个路由 DirectRouteA
public class DirectRouteA extends RouteBuilder {
/* (non-Javadoc)
* @see org.apache.camel. builder.RouteBuilder #configure()
*/
@Override
public void configure() throws Exception {
from("jetty: http://0.0.0.0:8282/ dynamicCamel")
.setExchangePattern (ExchangePattern.InOnly)
.recipientList().jsonpath ("$.data.routeName") .delimiter (",")
.end()
.process(new OtherProcessor());
}
}
第二个和第三个路由
/**
* @author yinwenjie
*/
public class DirectRouteB extends RouteBuilder
{
/* (non-Javadoc)
* @see org.apache.camel.builder.RouteBuilder#configure()
*/
@Override
public void configure() throws Exception {
// 第二个路由和第三个路由的代码都相似
// 唯一不同的是类型
from("direct:directRouteB")
.to("log:DirectRouteB?showExchangeId=true");
}
}
注册到Camel服务中,并开始执行
......
public static void main(String[] args) throws
Exception {
// 这是camel上下文对象,整个路由的驱动全靠它了。
ModelCamelContext camelContext = new DefaultCamelContext();
// 启动route
camelContext.start();
// 将我们编排的一个完整消息路由过程,加入到上下文中
camelContext.addRoutes((new DynamicCamel()).new
DirectRouteA());
camelContext.addRoutes((new DynamicCamel()).new
DirectRouteB());
camelContext.addRoutes((new DynamicCamel()).new
DirectRouteC());
// 通用没有具体业务意义的代码,只是为了保证主线程不退出
synchronized (DynamicCamel.class) {
DynamicCamel.class.wait();
}
}
......
总结:DirectRouteB路由和DirectRouteC路由中的代码非常简单,
就是从通过direct连接到本路由的上一个路由实例中获取并打印Exchange对象的信息。
所以各位读者可以看到以上代码片段只列举了DirectRouteB的代码信息。
DirectRouteA路由中“ExchangePattern.InOnly”的作用在上文中已经讲过,这里就不再进行赘述了。
需要重点说明的是recipientList方法,这个方法可以像multicast方法那样进行并发执行或者运行线程池的设置,
但是在DirectRouteA的代码中我们并没有那样做,这是为了让读者看清除recipientList或者multicast方法的顺序执行执行效果。
以下是我们启动Camel服务后,从Postman(或者其他测试工具)传入的JSON格式的信息:
recipientList方法将以 .data.routeName 中指定的路由信息动态决定一下个或者多个消息接收者,
以上JSON片段中我们指定了两个“direct:directRouteB,direct:directRouteC”。
那么recipientList会使用delimiter方法中设置的“,”作为分隔符来分别确定这两个接收者。
对比:静态路由和动态路由在执行效果上有很多相似之处。
例如在两种路径选择方式中,路由分支上的接收者中使用的Exchange对象的来源
都是对上一执行元素所输出的Exchange对象的复制,这些Exchange对象除了其中携带的业务内容相同外,
ExchangeID是不一样,也就是说每个路由分支的Exchange对象都不相同。
所以各路由分支的消息都不受彼此影响。另外动态路由和静态路由都支持对路由分支的顺序执行和并发执行,
都可以为并发执行设置独立的线程池。
总结:
从以上执行效果中我们可以看到,由于我们没有设置动态路由是并发执行,
所以各个需要执行的路由分支都是由名为【qtp1896561093-16】的Camel服务线程依次执行,
并且每个路由分支的Exchange对象都不受彼此影响。另外,请注意以上执行结果的最后一条日志信息,
它是在路由分支以外对OtherProcessor处理器的执行。由此可见无论路由分支如何执行,
都不会影响路由分支以外的元素执行时所使用的Exchange对象。
学习来源:http://www.uml.org.cn/zjjs/201801222.asp?artid=20340