与弹簧集成启动竞赛条件弹簧批次
问题描述:
对于我正在使用弹簧引导,弹簧批量和弹簧集成的应用程序。与弹簧集成启动竞赛条件弹簧批次
我的问题是,在启动时,当一切都自动配置并自动连线时,连接到RabbitMQ的弹簧集成@MessageEndpoints正开始处理队列中的可用消息。根据收到的消息,这些@MessageEndpoints尝试启动特定的弹簧式批处理作业,通过自动连接的JobRegistery查找。
由于所有自动配置,并非所有作业都被注册到使用的JobRegistery! (几秒钟后他们会)。
将所有弹簧批次作业注册到JobRegistery后,应启动@MessageEndpoints。这可能吗?也许以为ContextRefreshEvent?
答
我刚才看了一下代码,问题似乎是AutomaticJobRegistrar
使用上下文刷新事件来加载作业;它应该真的实施SmartLifecycle
并开始“早期”阶段。
弹簧集成组件实现SmartLifecycle
和入站端点(如兔端点)在后期开始。
我建议你打开一个JIRA对批处理 - 有一个在AutomaticJobRegistrar
代码TODO:
// TODO: With Spring 3 a SmartLifecycle is started automatically
作为变通,您可以设置autoStartup
到false
入站适配器(S)上使用您的自己的事件侦听器在上下文刷新事件上启动它们。
听众应该执行Ordered
; AutomaticJobRegistrar
为Ordered.LOWEST_PRECEDENCE
,因此您希望以较高的优先级(较低的优先级)运行。
答
加里罗素谢谢你在正确的方向推动!我已经解决它如下:
- 禁用我的集成XML中的入站通道的自动启动。
- SpringApplication.run()之后如果手动启动这些入站通道,通过getBeansOftype()找到。
。
public static void main(final String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(SpringBatchApplication.class, args);
startInboundChannelAdapters(context);
}
private static void startInboundChannelAdapters(ConfigurableApplicationContext context) {
Map<String, AmqpInboundChannelAdapter> adapters = context.getBeansOfType(AmqpInboundChannelAdapter.class);
adapters.forEach((name, adapter) -> {
if (!adapter.isRunning()) {
adapter.start();
}
});
}
很酷;是;这是一个有效的选择。我打开了一个[JIRA问题](https://jira.spring.io/browse/BATCH-2564)。 –