我正在使用Camel和Spring进行Java项目开发。我们希望在Spring完成所有操作并且Camel构建完所有路由后,触发单例bean的初始化方法。
我们不能在类创建时调用该方法,因为它与其他类具有动态链接,这些类是从@Component Spring注释中获取的,我们不知道这些类何时/是否已经加载,以便将init方法作为构造函数的一部分实际运行。
我该如何在Camel启动完成后仅调用一次方法或多个方法?
谢谢!
我正在使用Camel和Spring进行Java项目开发。我们希望在Spring完成所有操作并且Camel构建完所有路由后,触发单例bean的初始化方法。
我们不能在类创建时调用该方法,因为它与其他类具有动态链接,这些类是从@Component Spring注释中获取的,我们不知道这些类何时/是否已经加载,以便将init方法作为构造函数的一部分实际运行。
我该如何在Camel启动完成后仅调用一次方法或多个方法?
谢谢!
另一种简单的选择是使用camel-timer,它可以让你更加灵活。设置repeatCount为1,延迟时间足够长以便让所有内容初始化完成。你还可以添加基本的异常处理来进行延迟/重试等操作。
from("timer://runOnce?repeatCount=1&delay=5000").to("bean:runOnceBean");
在你的bean的一个方法中添加逻辑,并使用@PostConstruct进行注释 - spring将在此bean完全初始化并设置其所有依赖项后调用此方法。
@Component
class SomeClass {
@PostConstruct
void init() {
}
}
如果需要在整个 Spring 应用上下文完全初始化之后调用逻辑,则可以通过实现 LifeCycle 接口来实现。
@PostConstruct
在全局意义上是什么意思?如果我正在查找某种类型的所有 @Component
,例如使用 ApplicationContent.getBeansOfType(SomeType.class)
,它是否总是会选择这些组件的实例,即使 Spring 加载它们的顺序发生变化? - NightWolf<bean class="MyClass" init-method="start" destroy-method="stop"/>
来分别调用start()和stop()...我希望可能有类似于Camel Context的东西...你有使用LifeCycle
接口的示例吗? - NightWolfvoid afterApplicationStart(CamelContext camelContext);
在RoutesCollector
的onApplicationEvent
中添加如下内容:
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
}
};
}
<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的路由之前执行。因此,您可以在任何时候都使用带有定时器consumer的路由,在启动您的路由之前或之后。
正如之前的答案所暗示的那样,这更像是一个Spring而不是Camel的问题。在Spring中,您可以简单地实现InitializingBean并实现afterPropertiesSet方法。当装配完成时,将调用此方法。