我想运行一次路线并在路线完成时停止上下文。目前我在主Java类中使用通常的Thread.sleep(3000)来留下一些时间来完成路由,但它显然不准确,我的路线可能需要1秒或20秒我事先无法知道
Java类:
public static void main(String[] args) throws Exception {
try (ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("camel-context.xml")) {
CamelContext camelContext = SpringCamelContext.springCamelContext(context);
// context.start(); // apparently not necessary
camelContext.startRoute("route1");
try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); }
// context.stop(); // apparently not necessary
}
}
Spring xml:
<route id="route1" autoStartup="false">
<from uri="timer://runOnce?repeatCount=1&delay=3000" />
...
</route>
从Claus Ibsen阅读http://camel.465427.n5.nabble.com/Need-control-back-in-the-Main-routine-so-that-we-can-terminate-JVM-td4483312.html#a4484845特别是第4篇文章之后,我想在带有Thread.sleep()的循环中使用camelContext.getRouteStatus(),但无论我在哪里尝试获取路由状态代码(即使在Thread.sleep(3000)之后),状态总是&#34;开始&#34;。我不知道有什么其他方法来检测路线何时完成。
当使用Spring完成/所有路由时,建议停止Camel上下文的方法是什么?
答案 0 :(得分:2)
路由永远不会停止,因为路由没有complete
状态。它们只能启动,停止或暂停。如果路由处于启动状态,则该路由将始终运行,除非您执行某些操作以更改该路径。
要完成您所寻找的目标,您可以做以下几件事:
您可以使用controlbus
组件并在路线的最后一步停止路线。这样你就可以在你应该停止上下文时检查(例如你提到检查camelContext.getRouteStatus()
的方式)。
您可以写一个小Processor
,只要收到Exchange
,它就会停止camelContext
。准备好后,您将把它添加到路线的最后一步。
Camel支持onCompletion
回调,这可以等同于上面的选项。请参阅camel page。
可能第一个选项对您的用例来说最简单,但我会选择第二个选项。对我来说似乎更清洁。
答案 1 :(得分:1)
更优雅的方法是使用Java提供的同步机制,如CountDownLatch。主线程将等待Route线程打开锁存器。类似的东西:
CountDownLatch latch = new CountDownLatch(1);
camelContext.addRoutes(createRoute(latch));
和createRoute方法中的某处在路径末尾添加处理器以打开锁存器。这对我很有用。
.process(new Processor() {
@Override
public void process(Exchange exchange) throws Exception {
latch.countDown();
}
});