规则引擎(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

posted @ 2020-08-26 17:10  小窝蜗  阅读(741)  评论(0编辑  收藏  举报