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

时间:2011-10-10 14:24:57

标签: java spring apache-camel

我正在使用Camel& amp;弹簧。我们想在Spring完成它之后触发一个单例bean的初始化方法,并且Camel已经完成了所有路由的构建。

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

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

谢谢!

7 个答案:

答案 0 :(得分:19)

另一个提供更多灵活性的简单选项是使用camel-timer和repeatCount = 1以及一个足够长的延迟值来让所有内容初始化。你也可以添加基本的异常处理来延迟/重试等......

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

答案 1 :(得分:10)

如果在CamelContext启动所有路由等之后调用bean ,那么你可以像Ben建议的那样使用带有计时器的路由。

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

答案 2 :(得分:3)

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

在CamelContextConfiguration中,添加方法:

void afterApplicationStart(CamelContext camelContext);

onApplicationEvent的{​​{1}}中添加如下内容:

RoutesCollector

如果使用截至此日期的最新版本,则可以省略 if (camelContextConfigurations != null) { for (CamelContextConfiguration camelContextConfiguration : camelContextConfigurations) { camelContextConfiguration.afterApplicationStart(camelContext); } }

然后按如下所示创建一个Spring bean来添加你的代码:

if (camelContextConfigurations != null)

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

答案 3 :(得分:2)

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

@Component
class SomeClass {

 @PostConstruct
 void init() {
 }

}

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

答案 4 :(得分:1)

您可以尝试将camel上下文注入到单例bean中。在上下文完全初始化之前不会发生注入...包括构建所有路径。缺点是您可能实际上不需要bean中的上下文。我想知道将单例bean依赖关系链接到spring配置文件中的camelContext初始化,但不确定它是否会真正起作用。

答案 5 :(得分:1)

就像在答案之前已经暗示过这是一个春天而不是骆驼问题。在Spring中,您可以简单地实现InitializingBean并实现menthod AfterPropertiesSet。接线完成后调用。

答案 6 :(得分:0)

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

<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的路由之前执行。因此,您可以在路线开始之前或之后,使用您喜欢的定时器消费者路线。