2.14. OnCompletion
概述
OnCompletion DSL 名称用于定义在工作单元完成后 要采取的操作。工作单元是包括 整个交换的 Camel 概念。请参阅 第 34.1 节 “Exchanges”。onCompletion 命令具有以下功能:
-
OnCompletion命令的范围可以是全局的,也可以是每个路由。路由范围覆盖全局范围。 -
OnCompletion可以配置为在成功失败时触发。 -
onWhenpredicate 可以用来仅在某些情况下触发完成。 - 您可以定义是否使用线程池,但默认为没有线程池。
Route Only Scope forCompletion
当在交换 上指定了"Completion DSL"时,Camel 会关闭新的线程。这允许原始线程继续,而不会对 onCompletion 任务进行干扰。路由将只在完成时支持 一个。在以下示例中,触发 onle tion,无论交换在成功或失败时是否完成。这是默认操作。
from("direct:start")
.onCompletion()
// This route is invoked when the original route is complete.
// This is similar to a completion callback.
.to("log:sync")
.to("mock:sync")
// Must use end to denote the end of the onCompletion route.
.end()
// here the original route contiues
.process(new MyProcessor())
.to("mock:result");对于 XML,格式如下:
<route>
<from uri="direct:start"/>
<!-- This onCompletion block is executed when the exchange is done being routed. -->
<!-- This callback is always triggered even if the exchange fails. -->
<onCompletion>
<!-- This is similar to an after completion callback. -->
<to uri="log:sync"/>
<to uri="mock:sync"/>
</onCompletion>
<process ref="myProcessor"/>
<to uri="mock:result"/>
</route>
要在失败时触发 onCompletion,可以使用 onFailureOnly 参数。同样,若要触发成功的时间,请使用 onCompleteOnly 参数。
from("direct:start")
// Here onCompletion is qualified to invoke only when the exchange fails (exception or FAULT body).
.onCompletion().onFailureOnly()
.to("log:sync")
.to("mock:sync")
// Must use end to denote the end of the onCompletion route.
.end()
// here the original route continues
.process(new MyProcessor())
.to("mock:result");
对于 XML,onFailureOnly 和 onCompleteOnly 在 Completion 标签中以布尔值表示:
<route>
<from uri="direct:start"/>
<!-- this onCompletion block will only be executed when the exchange is done being routed -->
<!-- this callback is only triggered when the exchange failed, as we have onFailure=true -->
<onCompletion onFailureOnly="true">
<to uri="log:sync"/>
<to uri="mock:sync"/>
</onCompletion>
<process ref="myProcessor"/>
<to uri="mock:result"/>
</route>Completion 的全局范围
为 多个路由定义 on letion:
// define a global on completion that is invoked when the exchange is complete
onCompletion().to("log:global").to("mock:sync");
from("direct:start")
.process(new MyProcessor())
.to("mock:result");使用 onWhen
要在某些情况下触发 onCompletion,请使用 onWhen predicate。当消息的正文包含单词 Hello 时,以下示例将触发 onCompletion :
/from("direct:start")
.onCompletion().onWhen(body().contains("Hello"))
// this route is only invoked when the original route is complete as a kind
// of completion callback. And also only if the onWhen predicate is true
.to("log:sync")
.to("mock:sync")
// must use end to denote the end of the onCompletion route
.end()
// here the original route contiues
.to("log:original")
.to("mock:result");使用带有或没有线程池的 onCompletion
从 Camel 2.14 开始,在Completion 上 默认不使用线程池。要强制使用线程池,可将 executorService 或将 parallelProcessing 设置为 true。例如,在 Java DSL 中,使用以下格式:
onCompletion().parallelProcessing()
.to("mock:before")
.delay(1000)
.setBody(simple("OnComplete:${body}"));对于 XML,格式是:
<onCompletion parallelProcessing="true">
<to uri="before"/>
<delay><constant>1000</constant></delay>
<setBody><simple>OnComplete:${body}<simple></setBody>
</onCompletion>
使用 executorServiceRef 选项引用特定的线程池:
<onCompletion executorServiceRef="myThreadPool"
<to uri="before"/>
<delay><constant>1000</constant></delay>
<setBody><simple>OnComplete:${body}</simple></setBody>
</onCompletion>>在 Consumer Sends Response 之前运行 onCompletion
OnCompletion 可使用两种模式运行:
- AfterConsumer - 在消费者完成后运行的默认模式
-
BeforeConsumer - 在消费者将响应写入调用者前运行。这允许
完成修改交换(如添加特殊标头)或将 Exchange 记录为响应日志记录器。
例如,要将标头 创建的 添加到响应中,请使用 modeBeforeConsumer (),如下所示:
.onCompletion().modeBeforeConsumer()
.setHeader("createdBy", constant("Someone"))
.end()
对于 XML,将 mode 属性设置为 BeforeConsumer :
<onCompletion mode="BeforeConsumer">
<setHeader headerName="createdBy">
<constant>Someone</constant>
</setHeader>
</onCompletion>