Spring integration 分解DSL集成流

Spring integration 分解DSL集成流,spring-integration,Spring Integration,我一直在玩Spring集成(SI)DSL。我有一个定义了以下异步网关的Rest服务: @MessagingGateway public interface Provision { @Async @Gateway(requestChannel = "provision.input") ListenableFuture<List<ResultDto>> provision(List<ItemsDto> stuff); } @Messagi

我一直在玩Spring集成(SI)DSL。我有一个定义了以下异步网关的Rest服务:

@MessagingGateway
public interface Provision {
    @Async
    @Gateway(requestChannel = "provision.input")
    ListenableFuture<List<ResultDto>> provision(List<ItemsDto> stuff);
}
@MessagingGateway
公共接口规定{
@异步的
@网关(requestChannel=“provision.input”)
可上市的未来准备金(清单材料);
}
从逐行遍历中,我得到了以下示例IntegrationFlow

@Bean
public IntegrationFlow provision() {
    return f -> f
            .split(ArrayList.class, List::toArray)
            .channel(c -> c.executor(Executors.newCachedThreadPool()))
            .<ItemsDto, String>route(ItemsDto::getType, m -> m
                            .subFlowMapping("IPTV", sf -> sf
                                            .<ItemsDto, String>route(ItemsDto::getAction, m2 -> m2
                                                    .subFlowMapping("OPEN", sf2 -> sf2
                                                            .handle((p, h) -> iptvService.open((ItemsDto) p))))
                            )
            )
            .aggregate();
}
@Bean
公共集成流提供(){
返回f->f
.split(ArrayList.class,List::toArray)
.channel(c->c.executor(Executors.newCachedThreadPool()))
.route(ItemsDto::getType,m->m
.子流映射(“IPTV”,sf->sf
.route(ItemsDto::getAction,m2->m2
.子流映射(“打开”,sf2->sf2
.handle((p,h)->iptvService.open((ItemsDto)p)))
)
)
.aggregate();
}
如你所见,我有几层布线。我需要把事情分解一下。我尝试了几种不起作用的方法(在这里我没有得到响应…线程没有等待):

@Bean(name=“routerInput”)
私有消息通道路由输入(){
返回MessageChannels.direct().get();
}
@豆子
公共集成流提供(){
返回f->f
.split(ArrayList.class,List::toArray)
.channel(c->c.executor(Executors.newCachedThreadPool()))
.route(ItemsDto::getType,m->
m、 子流映射(“IPTV”,sf->sf.channel(“routerInput”))
)
.aggregate();
}
@豆子
公共集成流操作(){
返回IntegrationFlows.from(“routerInput”)
.route(ItemsDto::getAction,m->m
.子流映射(“打开”,sf->sf
.handle(p->iptvService.open((ItemsDto)p.getPayload()).get();
}
我显然在概念上遗漏了一些东西:)也许有人能帮我提出一个“如何做和为什么做”的意见吗

我有一个需要拆分的项目列表,按“类型”路由,然后按“操作”路由,最后聚合(包含处理程序的响应)。每个处理的项目都需要并行处理

提前谢谢

更新: 根据Artem的建议,我删除了所有异步内容。我把它削减到几乎没有

@Bean(name = "routerInput")
private MessageChannel routerInput() {
    return MessageChannels.direct().get();
}

@Bean
public IntegrationFlow provision() {
    return f -> f
            .split()
            .<ItemDto, String>route(ItemDto::getType, m ->
                    m.subFlowMapping("IPTV", sf -> sf.channel("routerInput")))
            .aggregate();
}

@Bean
public IntegrationFlow action() {
    return IntegrationFlows.from("routerInput")
            .<ItemDto, String>route(ItemDto::getAction, m -> m
                    .subFlowMapping("OPEN", sf -> sf
                            .handle((p, h) -> iptvService.open((ItemDto) p)))).get();
}
@Bean(name=“routerInput”)
私有消息通道路由输入(){
返回MessageChannels.direct().get();
}
@豆子
公共集成流提供(){
返回f->f
.split()
.route(ItemDto::getType,m->
m、 子流映射(“IPTV”,sf->sf.channel(“routerInput”))
.aggregate();
}
@豆子
公共集成流操作(){
返回IntegrationFlows.from(“routerInput”)
.route(ItemDto::getAction,m->m
.子流映射(“打开”,sf->sf
.handle((p,h)->iptvService.open((ItemDto)p))).get();
}
我让它通过改变来回应

.handle(p->

对此

.手柄((p,h)->


因此,它至少会响应,但不会聚合被拆分的3个测试项。输出由1项组成。我是否需要使用流收集?发布策略?这是否可以?

如果要将其拆分,使用
通道映射
可能比使用
子流映射
更简单

    @Bean
    public IntegrationFlow typeRoute() {
        return IntegrationFlows.from(foo())
                .split()
                .<ItemsDto, String>route(ItemsDto::getType, m -> m
                        .channelMapping("foo", "channel1")
                        .channelMapping("bar", "channel2"))
                .get();
    }

    @Bean
    public IntegrationFlow fooActionRoute() {
        return IntegrationFlows.from(channel1())
                .<ItemsDto, String>route(ItemsDto::getAction, m -> m
                        .channelMapping("foo", "channel3")
                        .channelMapping("bar", "channel4"))
                .get();
    }

    @Bean
    public IntegrationFlow barActionRoute() {
        return IntegrationFlows.from(channel1())
                .<ItemsDto, String>route(ItemsDto::getAction, m -> m
                        .channelMapping("foo", "channel5")
                        .channelMapping("bar", "channel6"))
                .get();
    }

    @Bean
    public IntegrationFlow fooFooHandle() {
        return IntegrationFlows.from(channel3())
                // handle
                .channel(aggChannel())
                .get();
    }
并行性是通过使用
ExecutorChannel
s

    @Bean
    public MessageChannel channel1() {
        return new ExecutorChannel(exec());
    }

    @Bean
    public MessageChannel channel2() {
        return new ExecutorChannel(exec());
    }

    @Bean
    public MessageChannel channel3() {
        return new DirectChannel();
    }

    @Bean
    public MessageChannel channel4() {
        return new DirectChannel();
    }

    @Bean
    public MessageChannel channel5() {
        return new DirectChannel();
    }

    @Bean
    public MessageChannel channel6() {
        return new DirectChannel();
    }

    @Bean
    public MessageChannel aggChannel() {
        return new DirectChannel();
    }

我认为您的配置中没有任何大问题,它确实应该可以工作

想要我不喜欢的有:

  • 如果您使用
    async
    Gateway(
    ListenableFuture
    ),您不需要在那里进行
    @async
    注释,因为它已经由Gateway契约提供

  • 如果您的
    负载
    已经是
    列表
    ,则不需要转换
    列表::到阵列
    。只需使用
    .split()
    而不使用参数即可

  • 这就是设计风格


    我还不确定问题出在哪里,但是您是否介意让您的整个流程同步,并在这里与我们共享流程的
    调试
    ,并指出您看到问题的地方。

    将聚合移动到“action”Bean,它就起作用了。 谢谢你的耐心:)

        // fooBarHandle(), barFooHandle(), barBarHandle()
    
    
        @Bean IntegrationFlow agg() {
            return IntegrationFlows.from(aggChannel())
                    .aggregate()
                    .get();
        }
    
        @Bean
        public MessageChannel channel1() {
            return new ExecutorChannel(exec());
        }
    
        @Bean
        public MessageChannel channel2() {
            return new ExecutorChannel(exec());
        }
    
        @Bean
        public MessageChannel channel3() {
            return new DirectChannel();
        }
    
        @Bean
        public MessageChannel channel4() {
            return new DirectChannel();
        }
    
        @Bean
        public MessageChannel channel5() {
            return new DirectChannel();
        }
    
        @Bean
        public MessageChannel channel6() {
            return new DirectChannel();
        }
    
        @Bean
        public MessageChannel aggChannel() {
            return new DirectChannel();
        }