我正在使用Camel& amp;弹簧。我们想在Spring完成它之后触发一个单例bean的初始化方法,并且Camel已经完成了所有路由的构建。
我们不能在类创建时调用该方法,因为它与从@Component spring注释中获取的其他类具有动态链接,并且我们不知道何时/是否已经加载这些类以实际运行init方法为构造函数的一部分。
如何在Camel启动完成后立即调用一个或多个方法来运行?
谢谢!
答案 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的路由之前执行。因此,您可以在路线开始之前或之后,使用您喜欢的定时器消费者路线。