Spring Integration 4 - configuring a LoadBalancingStrategy in Java DSL

冷暖自知 提交于 2019-12-13 01:29:49

问题


I have a simple Spring Integration 4 Java DSL flow which uses a DirectChannel's LoadBalancingStrategy to round-robin Message requests to a number of possible REST Services (i.e. calls a REST service from one of two possible service endpoint URIs).

How my flow is currently configured:

@Bean(name = "test.load.balancing.ch")
public DirectChannel testLoadBalancingCh() {

    LoadBalancingStrategy loadBalancingStrategy = new RoundRobinLoadBalancingStrategy();
    DirectChannel directChannel = new DirectChannel(loadBalancingStrategy);
    return directChannel;
}

@Bean
public IntegrationFlow testLoadBalancing0Flow() {

    return IntegrationFlows.from("test.load.balancing.ch")
            .handle(restHandler0())
            .channel("test.result.ch")
            .get();     
}

@Bean
public IntegrationFlow testLoadBalancing1Flow() {

    return IntegrationFlows.from("test.load.balancing.ch")
            .handle(restHandler1())
            .channel("test.result.ch")
            .get();     
}

@Bean
public HttpRequestExecutingMessageHandler restHandler0() {
    return createRestHandler(endpointUri0, 0);
}

@Bean
public HttpRequestExecutingMessageHandler restHandler1() {
    return createRestHandler(endpointUri1, 1);
}

private HttpRequestExecutingMessageHandler createRestHandler(String uri, int order) {

    HttpRequestExecutingMessageHandler handler = new HttpRequestExecutingMessageHandler(uri);
    // handler configuration goes here..
    handler.setOrder(order);
    return handler;

}

My configuration works, but I am wondering whether there is a simpler/better way of configuring the flow using Spring Integration's Java DSL?

Cheers, PM


回答1:


First of all the RoundRobinLoadBalancingStrategy is the default one for the DirectChannel. So, can get rid of the testLoadBalancingCh() bean definition at all.

Further, to avoid duplication for the .channel("test.result.ch") you can configure it on the HttpRequestExecutingMessageHandler as setOutputChannel().

From other side your configuration is so simple that I don't see reason to use DSL. You can achieve the same just with annotation configuration:

@Bean(name = "test.load.balancing.ch")
public DirectChannel testLoadBalancingCh() {
    return new DirectChannel();
}

@Bean(name = "test.result.ch")
public DirectChannel testResultCh() {
    return new DirectChannel();
}

@Bean
@ServiceActivator(inputChannel = "test.load.balancing.ch")
public HttpRequestExecutingMessageHandler restHandler0() {
    return createRestHandler(endpointUri0, 0);
}

@Bean
@ServiceActivator(inputChannel = "test.load.balancing.ch")
public HttpRequestExecutingMessageHandler restHandler1() {
    return createRestHandler(endpointUri1, 1);
}

private HttpRequestExecutingMessageHandler createRestHandler(String uri, int order) {

    HttpRequestExecutingMessageHandler handler = new HttpRequestExecutingMessageHandler(uri);
    // handler configuration goes here..
    handler.setOrder(order);
    handler.setOutputChannel(testResultCh());
    return handler;

}

From other side there is MessageChannels builder factory to allow to simplify loadBalancer for your case:

@Bean(name = "test.load.balancing.ch")
public DirectChannel testLoadBalancingCh() {
    return MessageChannels.direct()
             .loadBalancer(new RoundRobinLoadBalancingStrategy())
             .get();
}

However, I can guess that you want to avoid duplication within DSL flow definition to DRY, but it isn't possible now. That's because IntegrationFlow is linear to tie endoints bypassing the boilerplate code for standard objects creation.

As you see to achieve Round-Robin we have to duplicate, at least, inputChannel, to subscribe several MessageHandlers to the same channel. And we do that in the XML, via Annotations and, of course, from DSL.

I'm not sure that it will be so useful for real applications to provide a hook to configure several handlers using single .handle() for the same Round-Robin channel. Because the further downstream flow may not be so simple as your .channel("test.result.ch").

Cheers



来源:https://stackoverflow.com/questions/25264395/spring-integration-4-configuring-a-loadbalancingstrategy-in-java-dsl

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!