骆驼路由器中的end与endChoice之间的区别 - 不是通常的问题

23

首先,是的,我已经搜索过了,并且,是的,我已经阅读了每个人都指向的同一份Apache文档。 :-) 我认为有点混淆,我认为我知道一个答案,所以让我举一个我认为是正确的例子,并跟随我认为的答案。谢谢。哦,我知道一些endChoice()行并不是严格必要的,Camel会处理好它,但除非有理由不使用它们,否则我喜欢块被清晰地划分。

.choice()
    .when(X1)
        // do stuff
        .choice()
            .when(Y)
                //do more stuff
            .endChoice()  // close inner when block
        .end() // close inner choice block
    .endChoice()  // close first outer when
    .when(X2)
        // do other stuff
    .endChoice()  // close second outer when
.end() // close outer choice

因此,我最初观察API时,认为end()是用于关闭choice和split之类的内容,而endChoice()是用于关闭像when和otherwise这样的choice选项。实际上,后者看起来更像是返回ChoiceDefinition的end()。这使名称更好了一些。

但是,如果我删除标记为“close inner choice block”的end(),这意味着我会继续到下一行的endChoice()。那么这是否会关闭内部choice块呢?考虑到when(X2)仍然在when(X1)块内,所以我认为我需要用endChoice()替换end()而不是将其删除。因此结果应如下所示:

.choice()
    .when(X1)
        // do stuff
        .choice()
            .when(Y)
                //do more stuff
            .endChoice()  // close inner when block
        .endChoice() // close inner choice block
    .endChoice()  // close first outer when
    .when(X2)
        // do other stuff
    .endChoice()  // close second outer when
.end() // close outer choice

这是在Camel中处理这种情况的方式吗?还是我只是错过了更简单的方法?感谢您的时间。

2个回答

33

简短回答: 我会自责并指出你正在做错事,不应该嵌套选项。

详细回答: 我继承了一个复杂的路由构建器,并试图清理它以使其更清晰。但是添加end()或endChoice()只会破坏事情。而且,是的,上面的修复方法仍然会破坏事情。我不明白Camel如何知道要去哪个块。研究并试图找到嵌套的良好示例最终让我明白了一个事实,即Camel并没有真正设计用于嵌套选择。它允许这样做,但由于Java的限制,它无法很好地处理。所以我尝试删除我的嵌套选项。虽然这是可能的,但这意味着丑陋的冗余条件语句,例如:

choice()
  .when(x and a)
    //do stuff xa
  .when(x not a)
    // do other x stuff
  .when(y and a)
    // do y stuff

只有我的实现至少还有另一个层次。通过进一步思考和回忆我所读过的内容,带来了第二个启示。Camel 的整个意义在于指导路由。每个选择的 when 块应该只是将进程引导到一个路线上。它不应该去思考、处理或者做任何事情。最终,我们的团队将进行重构,将大部分逻辑从路由构建器中移除到一个 bean 中。我们将要达成的设计将会是简单明了的:

   from(uri)
     .bean(class, method)  // do any processing
     .choice()
       .when(header("result").isEqualTo("A")
          .to(routeA)
       .endChoice()
       .when(header("result").isEqualTo("B")
          .to(routeB)
       .endChoice()
       .when(header("result").isEqualTo("C")
          .to(route)
       .endChoice()
      .end()

我的建议是避免嵌套选择,特别是复杂的选择。虽然可能能让它工作,但当您以后需要进行更改时,您将无法信任它。如果您发现自己想使用嵌套选择,请检查您想要实现什么,并决定它是否真的属于路由构建器。


3
好建议,我也尽量避免嵌套选择。你的同事或未来的自己会感谢你的 ;). - helpermethod
我建议将这种情况分解成多个路由,每个路由都包含自己的单个 choice - when 块。 - Muhammad Arslan Akhtar

13

虽然有点晚,但可能会有所帮助。

嵌套的选择定义在Camel中完美运行。只是您的终止器不正确:

  • .endChoice() --> 用于关闭“when”谓词
  • .end() --> 用于关闭整个“choice”块

我知道,语法有点令人困惑。

因此,在您的情况下:

.choice()
    .when(X1)
        // do stuff

        .choice()
            .when(Y)
                //do more stuff
            .endChoice() // close Y condition

        .end() // close inner choice block

    .endChoice() // close X1 condition

    .when(X2)
        // do other stuff
    .endChoice() // close X2 condition

    .otherwise()
        // default case
    .endChoice() // close default condition

.end()

实际上,您不必关闭所有when谓词,仅针对多个子路由。在我看来,非常细致地缩进会有很大帮助。


2
这是许多例子之一,其中Camel的“语法”可能会更好:( - user272735
当我在一个内部选择块中(没有.otherwise())并且只想关闭该块时,我需要调用.endChoice().end()而不仅仅是.end(),原因不明,否则会破坏层次结构。不确定是否总是这样,但我对Camel在这方面不太信任。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接