规则引擎(Apache camel) 学习三
1.特殊的Endpoint Direct
介绍:
Endpoint Direct用于在两个编排好的路由间实现Exchange消息的连接,上一个路由中由最后一个元素处理完的Exchange对象,
将被发送至由Direct连接的下一个路由起始位置(http://camel.apache.org/direct.html)。
注意,两个被连接的路由一定要是可用的,并且存在于同一个Camel服务中。
以下的例子说明了Endpoint Direct的简单使用方式。
实现:
package com.yinwenjie.test.cameltest.helloworld;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.model.ModelCamelContext;
/**
* 测试两个路由的连接
* @author yinwenjie
*/
public class DirectCamel {
public static void main(String[] args) throws
Exception {
// 这是camel上下文对象,整个路由的驱动全靠它了。
ModelCamelContext camelContext = new DefaultCamelContext();
// 启动route
camelContext.start();
// 首先将两个完整有效的路由注册到Camel服务中
camelContext.addRoutes((new DirectCamel()).new
DirectRouteA());
camelContext.addRoutes((new DirectCamel()).new
DirectRouteB());
// 通用没有具体业务意义的代码,只是为了保证主线程不退出
synchronized (DirectCamel.class) {
DirectCamel.class.wait();
}
}
/**
* DirectRouteA 其中使用direct 连接到 DirectRouteB
* @author yinwenjie
*/
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/directCamel")
// 连接路由:DirectRouteB
.to("direct:directRouteB")
.to("log:DirectRouteA?showExchangeId=true");
}
}
/**
* @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");
}
}
}
以上代码片段中,我们编排了两个可用的路由(尽管两个路由都很简单,但确实是两个独立的路由)命名为DirectRouteA和DirectRouteB。
其中DirectRouteA实例在最后一个Endpoint控制端点(direct:directRouteB)中使用Endpoint Direct
将Exchange消息发送到DirectRouteB实例的开始位置。以下是控制台输出的内容:
[2016-06-26 09:54:38] INFO qtp231573738-21
Exchange[Id: ID-yinwenjie-240-54473-1466906074572-0-1,
ExchangePattern: InOut, BodyType: org.apache.camel.converter.stream.InputStreamCache,
Body: [Body is instance of org.apache.camel.StreamCache]] (MarkerIgnoringBase.java:96)
[2016-06-26 09:54:38] INFO qtp231573738-21
Exchange[Id: ID-yinwenjie-240-54473-1466906074572-0-1,
ExchangePattern: InOut, BodyType: org.apache.camel.converter.stream.InputStreamCache,
Body: [Body is instance of org.apache.camel.StreamCache]] (MarkerIgnoringBase.java:96)
总结:从以上执行效果我们可以看到,被连接的两个路由使用的Exchange对象是同一个,
也就是说在DirectRouteB路由中如果Exchange对象中的内容发生了变化就会在随后继续执行的DirectRouteA路由中产生影响。
Endpoint Direct元素在我们实际使用Camel进行路由编排时,应用频度非常高。
因为它可以把多个已编排好的路由按照业务要求连接起来,形成一个新的路由,保持原有路由的良好重用。
2.Processor 处理器
介绍:Camel中另一个重要的元素是Processor处理器,它用于接收从控制端点、
路由选择条件又或者另一个处理器的Exchange中传来的消息信息,并进行处理。
Camel核心包和各个Plugin组件都提供了很多Processor的实现,
开发人员也可以通过实现org.apache.camel.Processor接口自定义处理器(后者是通常做法)。
功能:既然是做编码,那么我们自然可以在自定义的Processor处理器中做很多事情。
这些事情可能包括处理业务逻辑、建立数据库连接去做业务数据存储、建立和某个第三方业务系统的RPC连接,
但是我们一般不会那样做——那是Endpoint的工作。
Processor处理器中最主要的工作是进行业务数据格式的转换和中间数据的临时存储。
这样做是因为Processor处理器是Camel编排的路由中,主要进行Exchange输入输出消息交换的地方。
举例:不过开发人员当然可以在Processor处理器中连接数据库。
例如开发人员需要根据上一个Endpoint中携带的“订单编号前缀”信息,
在Processor处理器中连接到一个独立的数据库中(或者缓存服务中)查找其对应的路由信息,
以便动态决定下一个路由路径。由于Camel支持和JAVA语言的Spring框架无缝集成,
所以要在Processor处理器中操作数据库只需要进行非常简单的配置。
代码:
以下代码片段是自定义的Processor处理器实现,其中的process(Exchange exchange)方法是必须进行实现的:
// 一个自定义处理器的实现
// 就是我们上文看到过的处理器实现了
public class OtherProcessor implements Processor
{
......
@Override
public void process(Exchange exchange) throws
Exception {
Message message = exchange.getIn();
String body = message.getBody().toString();
//===============
// 您可以在这里进行数据格式转换
// 并且将结果存储到out message中
//===============
// 存入到exchange的out区域
if(exchange.getPattern() == ExchangePattern.InOut)
{
Message outMessage = exchange.getOut();
outMessage.setBody(body + " || other out");
}
}
......
}
注意:处理器Processor是和控制端点平级的概念。
要看一个URI对应的实现是否是一个控制端点,最根本的就是看这个实现类是否实现了org.apache.camel.Endpoint接口;
而要看一个路由中的元素是否是Processor处理器,最根本的就是看这个类是否实现了org.apache.camel.Processor接口。
学习来源:http://www.uml.org.cn/zjjs/201801222.asp?artid=20340