2016-12-14 148 views
0

对于我正在使用弹簧引导,弹簧批量和弹簧集成的应用程序。与弹簧集成启动竞赛条件弹簧批次

我的问题是,在启动时,当一切都自动配置并自动连线时,连接到RabbitMQ的弹簧集成@MessageEndpoints正开始处理队列中的可用消息。根据收到的消息,这些@MessageEndpoints尝试启动特定的弹簧式批处理作业,通过自动连接的JobRegistery查找。

由于所有自动配置,并非所有作业都被注册到使用的JobRegistery! (几秒钟后他们会)。

将所有弹簧批次作业注册到JobRegistery后,应启动@MessageEndpoints。这可能吗?也许以为ContextRefreshEvent?

回答

0

我刚才看了一下代码,问题似乎是AutomaticJobRegistrar使用上下文刷新事件来加载作业;它应该真的实施SmartLifecycle并开始“早期”阶段。

弹簧集成组件实现SmartLifecycle和入站端点(如兔端点)在后期开始。

我建议你打开一个JIRA对批处理 - 有一个在AutomaticJobRegistrar代码TODO:

// TODO: With Spring 3 a SmartLifecycle is started automatically 

作为变通,您可以设置autoStartupfalse入站适配器(S)上使用您的自己的事件侦听器在上下文刷新事件上启动它们。

听众应该执行Ordered; AutomaticJobRegistrarOrdered.LOWEST_PRECEDENCE,因此您希望以较高的优先级(较低的优先级)运行。

0

加里罗素谢谢你在正确的方向推动!我已经解决它如下:

  1. 禁用我的集成XML中的入站通道的自动启动。
  2. 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(); 
     } 
    }); 
} 
+0

很酷;是;这是一个有效的选择。我打开了一个[JIRA问题](https://jira.spring.io/browse/BATCH-2564)。 –