Camel end vs endChoice - 不是通常的查询

Sco*_*Law 15 java apache-camel

首先,是的,我已经搜索了,是的,我已经阅读了每个人指向的相同的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
Run Code Online (Sandbox Code Playgroud)

所以,我原来看看API,我认为end()用于关闭诸如choice和split之类的东西,而endChoice()用于关闭选择选项,比如when和otherwise.它看起来更像后者实际上是一个返回ChoiceDefinition的end().这使得这个名字好一点.

但是,如果我取出标有'close inner choice block'的end(),这意味着我继续下一行,即endChoice().这会关闭内部选择块吗?鉴于此,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
Run Code Online (Sandbox Code Playgroud)

那么这是在Camel中处理这个问题的方法吗?或者有一种更简单的方法,我只是缺少?谢谢你的时间.

Sco*_*Law 20

简短的回答: 我会自称为此,所以没有其他人必须这样做,答案是你做错了,不应该有嵌套的选择.

长期回答:我继承了一个复杂的路线建设者,并试图清理它以使其更清晰.但是直截了当并且放入end()或endChoice()只会破坏事物.并且,是的,上述修复仍然破坏了一些事情.我不明白骆驼怎么知道要去哪个街区.研究并试图找到嵌套的好例子最终推动了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
Run Code Online (Sandbox Code Playgroud)

只有我的至少还有另一个级别.进一步思考和回忆我读过的东西带来了第二点启蒙.骆驼的重点是指挥路线.块的每个选择应该只是将进程指向路由.它不应该是思考,处理或任何东西.最后,我们的小组将重构以将路由构建器中的大部分逻辑移除到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()
Run Code Online (Sandbox Code Playgroud)

我给你的建议是避免嵌套选择.特别复杂的.您可能会让它工作,但是当您必须稍后进行更改时,您将无法信任它.如果您发现自己想要使用嵌套选项,请检查您要完成的操作并确定它是否真的属于路径构建器.

  • 好建议,我也尽量不做出选择.你的同事或你未来的自己会感谢你;). (3认同)

小智 13

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

嵌套选择定义与 Camel 配合得很好。只有你的终结者是错误的:

  • .endChoice()--> 关闭“when”谓词
  • .end()--> 关闭整个“选择”块

我知道,语法有点混乱。

所以在你的情况下:

.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()
Run Code Online (Sandbox Code Playgroud)

实际上,您不必关闭所有when谓词,只需关闭多个子路由即可。以我的拙见,对缩进进行超级细致的处理很有帮助。

  • 这是 Camel“语法”可以更好的众多例子之一:( (2认同)