Apache camel 驼峰和春天:路线完成时停止上下文

Apache camel 驼峰和春天:路线完成时停止上下文,apache-camel,Apache Camel,我想运行一次路由,并在路由完成时停止上下文。目前,我在主Java类中使用通常的Thread.sleep(3000)来为路由完成留出一些时间,但这显然不准确,我的路由可能需要1秒或20秒,我无法提前知道 Java类: public static void main(String[] args) throws Exception { try (ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext

我想运行一次路由,并在路由完成时停止上下文。目前,我在主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
    }
}
SpringXML:

<route id="route1" autoStartup="false">
    <from uri="timer://runOnce?repeatCount=1&amp;delay=3000" />
    ...
</route>

...
特别是在阅读了Claus Ibsen的第4篇文章之后,我想在一个带有Thread.sleep()的循环中使用camelContext.getRouteStatus(),但无论我在哪里尝试在代码中获取路由状态(即使在Thread.sleep(3000)之后),状态总是“启动”。我不知道还有什么其他方法可以检测路线何时完成


当使用Spring完成/所有路由时,建议使用什么方法停止骆驼上下文?

路由将永远不会停止,因为路由没有
complete
状态。它们可以只是启动、停止或暂停。如果路由处于“已启动”状态,则它将始终处于运行状态,除非您采取措施更改该状态

要实现您的目标,您可以做以下几件事:

  • 您可以使用
    controlbus
    组件,在路线的最后一步停止路线。这样,您可以在应该停止上下文时进行检查(例如,您提到的检查
    camelContext.getRouteStatus()

  • 您可以编写一个小型
    处理器
    ,每当它接收到
    交换
    时,它就会停止
    上下文
    。准备好后,您将其添加到路线的最后一步

  • Camel支持
    onCompletion
    回调,这与上面的选项相当。看


也许,第一个选项对于您的用例来说是最简单的,但是我会选择第二个选项。这对我来说似乎更干净。

路线永远不会停止,因为路线没有
完成状态。它们可以只是启动、停止或暂停。如果路由处于“已启动”状态,则它将始终处于运行状态,除非您采取措施更改该状态

要实现您的目标,您可以做以下几件事:

  • 您可以使用
    controlbus
    组件,在路线的最后一步停止路线。这样,您可以在应该停止上下文时进行检查(例如,您提到的检查
    camelContext.getRouteStatus()

  • 您可以编写一个小型
    处理器
    ,每当它接收到
    交换
    时,它就会停止
    上下文
    。准备好后,您将其添加到路线的最后一步

  • Camel支持
    onCompletion
    回调,这与上面的选项相当。看


也许,第一个选项对于您的用例来说是最简单的,但是我会选择第二个选项。对我来说似乎更干净。

一种更优雅的方法是使用类似Java的CountDownLatch提供的同步机制。主线程将等待路由线程打开闩锁。比如:

 CountDownLatch latch = new CountDownLatch(1);
 camelContext.addRoutes(createRoute(latch));
在createRoute方法的某个地方,在路由的末尾添加一个处理器以打开闩锁。这对我来说非常有效

.process(new Processor() {
    @Override
    public void process(Exchange exchange) throws Exception {
        latch.countDown();                                
    }
});

更优雅的方法是使用类似Java的CountDownLatch提供的同步机制。主线程将等待路由线程打开闩锁。比如:

 CountDownLatch latch = new CountDownLatch(1);
 camelContext.addRoutes(createRoute(latch));
在createRoute方法的某个地方,在路由的末尾添加一个处理器以打开闩锁。这对我来说非常有效

.process(new Processor() {
    @Override
    public void process(Exchange exchange) throws Exception {
        latch.countDown();                                
    }
});

事实上,我已经在路径的末尾有了一个处理器,所以我会选择你的第二个选项,但是我仍然需要在主类中使用try{Thread.sleep(3000);}和一个大的数字,对吗?因为正如您在我的代码中所看到的,即使没有context.stop(),上下文也会立即停止……事实上,我已经在路由的末尾有了一个处理器,所以我会使用您的第二个选项,但是我仍然需要在主类中使用try{Thread.sleep(3000);}来获得一个大的数字,对吗?因为正如您在我的代码中看到的,即使没有context.stop()上下文也会立即停止。。。