Apache Camel - 在启动时触发任务仅运行一次

发布于 2024-12-08 22:53:48 字数 250 浏览 0 评论 0原文

我正在使用 Camel & 开发一个 Java 项目。春天。我们希望在 Spring 完成其工作并且 Camel 完成构建所有路由后触发单例 bean 上的初始化方法。

我们无法在类创建时调用该方法,因为它具有到从 @Component spring 注释中获取的其他类的动态链接,并且我们不知道这些类何时/是否已加载,以实际运行 init 方法作为构造函数。

如何在 Camel 启动完成后调用一个或多个方法仅运行一次?

谢谢!

I am working on a Java project using Camel & Spring. We would like to trigger an initialize method on a singleton bean after Spring finished doing its thing and Camel has finished building all routes.

We cant call the method at class creation time as it has dynamic linkings to other classes that it picks up from the @Component spring annotation and we dont know when/if these classes have been loaded yet to actually run the init method as part of a constructor.

How can I go about invoking a method or methods to run only once right after Camel startup is complete?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

单挑你×的.吻 2024-12-15 22:53:48

另一个为您提供更多灵活性的简单选项是使用 camel-timer 和 RepeatCount=1和一个足够长的延迟值,让一切都初始化。您还可以添加基本的异常处理来延迟/重试等...

from("timer://runOnce?repeatCount=1&delay=5000").to("bean:runOnceBean");

another simple option which gives you a little more flexibility is to use camel-timer with a repeatCount=1 and a delay value long enough to let everything initialize. you can also add basic exception handling to delay/retry, etc...

from("timer://runOnce?repeatCount=1&delay=5000").to("bean:runOnceBean");
绾颜 2024-12-15 22:53:48

如果 bean 必须 在 CamelContext 启动所有路由等之后调用,那么您可以按照 Ben 的建议使用带有计时器的路由。

一个可能更好的替代方案是使用 Camel 的 EventNotifier API。然后调用正在触发的 CamelContextStartedEvent 上的逻辑。
有关 EventNotifier API 的一些详细信息,请参见:http:// /camel.apache.org/eventnotifier-to-log-details-about-all-sent-exchanges.html

If the bean must be invoked after CamelContext has started all the routes etc, then you can as Ben suggest use a route with a timer.

A possible better alternative is to use the EventNotifier API from Camel. And then invoke the logic on the CamelContextStartedEvent being fired.
Some details on the EventNotifier API here: http://camel.apache.org/eventnotifier-to-log-details-about-all-sent-exchanges.html

月下凄凉 2024-12-15 22:53:48

在 bean 的方法中添加逻辑并使用 @PostConstruct 对其进行注释 - 一旦该 bean 完全初始化并设置了其所有依赖项,spring 将调用此方法。

@Component
class SomeClass {

 @PostConstruct
 void init() {
 }

}

如果在整个 Spring 应用程序上下文完全初始化后需要调用逻辑,您可以通过实现 LifeCycle 接口。

Add the logic in a method of your bean and annotate it with @PostConstruct - spring will invoke this method once this bean is fully initialized and all its dependencies are set.

@Component
class SomeClass {

 @PostConstruct
 void init() {
 }

}

If the logic needs to be invoked once the whole spring application context is fully initialized you can do that by implementing the LifeCycle interface.

初雪 2024-12-15 22:53:48

一种解决方案是修补几个文件(请参阅 PR https://github.com/apache/ Camel/pull/684):CamelContextConfiguration.java 和 RoutesCollector.java。

在 CamelContextConfiguration 中,添加方法:

void afterApplicationStart(CamelContext camelContext);

RoutesCollectoronApplicationEvent 中添加如下内容:

        if (camelContextConfigurations != null) {
            for (CamelContextConfiguration camelContextConfiguration : camelContextConfigurations) {
                camelContextConfiguration.afterApplicationStart(camelContext);
            }
        }

如果使用,则可以省略 if (camelContextConfigurations != null)截至目前的最新版本。

然后按如下方式创建一个 Spring bean 以添加您的代码:

@Bean
CamelContextConfiguration contextConfiguration() {
    return new CamelContextConfiguration() {

        @Override
        public void beforeApplicationStart(CamelContext camelContext) {
        }

        @Override
        public void afterApplicationStart(CamelContext camelContext) {
            // Put your code here
        }
    };
}

更新:此拉取请求已合并。

One solution would be to patch a couple of files (see PR https://github.com/apache/camel/pull/684): CamelContextConfiguration.java and RoutesCollector.java.

In CamelContextConfiguration, add the method:

void afterApplicationStart(CamelContext camelContext);

And in onApplicationEvent of RoutesCollector add something like:

        if (camelContextConfigurations != null) {
            for (CamelContextConfiguration camelContextConfiguration : camelContextConfigurations) {
                camelContextConfiguration.afterApplicationStart(camelContext);
            }
        }

You may omit the if (camelContextConfigurations != null) if using the latest version as of this date.

Then create a Spring bean as follows to add your code:

@Bean
CamelContextConfiguration contextConfiguration() {
    return new CamelContextConfiguration() {

        @Override
        public void beforeApplicationStart(CamelContext camelContext) {
        }

        @Override
        public void afterApplicationStart(CamelContext camelContext) {
            // Put your code here
        }
    };
}

UPDATE: This pull request has been merged.

盗梦空间 2024-12-15 22:53:48

您可以使用 Camel 中的启动顺序功能,该功能记录在 http:// camel.apache.org/configuring-route-startup-ordering-and-autostartup.html :-

<route startupOrder="1" id="thisOneGoesFirst">    
  <from uri="seda:foo"/>
  <to uri="mock:result"/>
</route>
<route startupOrder="2" id="thisOneGoesSecond">
  <from uri="direct:start"/>
  <to uri="seda:foo"/>
</route> 
<route id="thisOneGoesLast">
  <from uri="direct:bar"/>
  <to uri="seda:bar"/>
</route>

具有startupOrder属性的路由将按顺序执行,并且在所有没有startupOrder的路由之前执行。因此,您可以在路线开始之前或之后的任何时间点使用计时器消费者来制定路线。

You could use the startup order functionality in Camel documented at http://camel.apache.org/configuring-route-startup-ordering-and-autostartup.html :-

<route startupOrder="1" id="thisOneGoesFirst">    
  <from uri="seda:foo"/>
  <to uri="mock:result"/>
</route>
<route startupOrder="2" id="thisOneGoesSecond">
  <from uri="direct:start"/>
  <to uri="seda:foo"/>
</route> 
<route id="thisOneGoesLast">
  <from uri="direct:bar"/>
  <to uri="seda:bar"/>
</route>

where the routes with a startupOrder attribute will be executed in order and BEFORE all routes which have no startupOrder. So you can have your route with a timer consumer at which ever point you like, before or after your routes have been started.

删除→记忆 2024-12-15 22:53:48

您可以尝试将骆驼上下文注入到您的单例 bean 中。在上下文完全初始化之前,注入不会发生......包括所有路由的构建。缺点是您可能实际上不需要 bean 中的上下文。我在脑子里琢磨着将单例 bean 依赖项链接到 spring 配置文件中的camelContext 初始化的想法,但不确定这是否真的有效。

You might try injecting the camel context into your singleton bean. The injection will not occur until the context is fully initialized ... including the building of all routes. The downside being that you might not actually require the context within your bean. I'm fiddling around in my head with an idea of linking the singleton bean dependency to the camelContext initialization in the spring configuration file, but not sure that will actually work.

揽月 2024-12-15 22:53:48

就像之前的答案中已经暗示的那样,这是一个 Spring 问题而不是 Camel 问题。在Spring中,您可以简单地实现InitializingBean并实现afterPropertiesSet方法。接线完成后会调用此方法。

Like already hinted in the answers before this is rather a Spring than a Camel problem. In Spring you can simply implement InitializingBean and implement the menthod afterPropertiesSet. This is called when the wiring is done.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文