在动态(手动)流注册期间,从不为子流调用生命周期start()

时间:2016-08-26 11:41:46

标签: spring-integration

我使用IntegrationFlow的动态(手动)注册(通过IntegrationFlowContext),我的集成流程包含一个发布/订阅通道,其中一个订阅者是子流。事实证明,子流组件从未启动,因为子流(作为主流的集成组件)未添加到"生命周期"在StandardIntegrationFlow构造函数中列出,该构造函数仅检查AbstractEndpoint和EndpointSpec实例:

    @SuppressWarnings("unchecked")
StandardIntegrationFlow(Set<Object> integrationComponents) {
    this.integrationComponents = new LinkedHashSet<Object>(integrationComponents);
    for (Object integrationComponent : integrationComponents) {
        if (integrationComponent instanceof AbstractEndpoint) {
            this.lifecycles.add((Lifecycle) integrationComponent);
        }
        else if (integrationComponent instanceof EndpointSpec) {
            BeanNameAware endpoint = ((EndpointSpec<?, BeanNameAware, ?>) integrationComponent).get().getT1();
            this.lifecycles.add((Lifecycle) endpoint);
        }
    }
}

调用StandardIntegrationFlow start()方法时,将启动主流的所有组件,但不启动子流的所有组件。随后,不会调用EventDrivenConsumer的start()方法,并且MessageHandler(在我的情况下)永远不会订阅发布/订阅频道。

我认为问题在于上面的代码。

以下是展示此行为的测试用例(与静态定义流程的行为相比):

@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@DirtiesContext
public class SubflowTests {

@Autowired
public IntegrationFlowContext integrationFlowContext;

@Autowired
public IntegrationFlow staticFlow;

@Autowired
private PollableChannel result;

@Test
public void testStaticFlow() {
    integrationFlowContext.messagingTemplateFor("staticFlow").send(new GenericMessage<String>("test"));

    Message<?> receive = this.result.receive(1000);
    assertNotNull(receive);
    assertEquals("test", receive.getPayload());
}

@Test
public void testDynamicFlow() {
    integrationFlowContext.register("dynamicFlow", flow -> flow
            .publishSubscribeChannel(p -> p.subscribe(f -> f.handle(new BridgeHandler())
                    .channel(result))));

    integrationFlowContext.messagingTemplateFor("dynamicFlow").send(new GenericMessage<String>("test"));

    Message<?> receive = this.result.receive(1000);
    assertNotNull(receive);
    assertEquals("test", receive.getPayload());

}

@Configuration
@EnableIntegration
public static class ContextConfiguration {

    @Bean
    public IntegrationFlow staticFlow() {
        return flow -> flow
                .publishSubscribeChannel(p -> p.subscribe(f -> f.handle(new BridgeHandler())
                        .channel(result())));
    }

    @Bean
    public PollableChannel result() {
        return MessageChannels.queue().get();
    }
}
}

1 个答案:

答案 0 :(得分:0)

看起来这是一个错误:https://github.com/spring-projects/spring-integration-java-dsl/issues/106

在我们找出解决方案之前,请考虑不要使用子流。

预计这个新功能会有一些缺陷。