正确的方式分割,丰富项目,然后将每个项目发送到另一个渠道?

时间:2017-08-17 17:11:49

标签: spring spring-integration spring-integration-dsl

这是分割项目列表的正确方法,丰富每个项目,然后将每个这些丰富的项目发送到另一个渠道吗?

似乎即使每个项目都在丰富,只有最后一个项目被发送到输出通道......

以下是我的测试中的剪切器,我从流程中看到只调用了page2。

this.sitePackage = new Package();
this.sitePackage.add(page1);
this.sitePackage.add(page2);
this.sitePackage.add(page3);

//Publish using gateway
this.publishingService.publish(sitePackage);

如果我这样做......

this.sitePackage.add(page1);
this.sitePackage.add(page1);

this.sitePackage.add(page2);
this.sitePackage.add(page2);

this.sitePackage.add(page3);
this.sitePackage.add(page3);

我看到所有正在发布的页面,但最后一个是page2而不是page3(即使从调试我可以看到该实例具有第3页属性)。

似乎所有其他项目都被流程看到了......

我的流程是这样的......

从PublishPackage流程开始。这是主要的入口流程,旨在将项目拆分出来,并在丰富有效负载之后将每个项目发送给附加到publishPackageItem通道的流程......

@Bean
IntegrationFlow flowPublishPackage()
{
    return flow -> flow
        .channel(this.publishPackageChannel())
        .<Package>handle((p, h) -> this.savePackage(p))
        .split(Package.class, this::splitPackage)
        .channel(this.publishPackageItemChannel());
}

@Bean
@PublishPackageChannel
MessageChannel publishPackageChannel()
{
    return MessageChannels.direct().get();
}

@Bean
@PublishPackageItemChannel
MessageChannel publishPackageItemChannel()
{
    return MessageChannels.direct().get();
}

@Splitter
List<PackageEntry> splitPackage(final Package bundle)
{
    final List<PackageEntry> enrichedEntries = new ArrayList<>();
    for (final PackageEntry entry : bundle.getItems())
    {
       enrichedEntries.add(entry);
    }

    return enrichedEntries;
}

@Bean
GatewayProxyFactoryBean publishingGateway()
{
    final GatewayProxyFactoryBean proxy = new GatewayProxyFactoryBean(PublishingService.class);
    proxy.setBeanFactory(this.beanFactory);
    proxy.setDefaultRequestChannel(this.publishPackageChannel());
    proxy.setDefaultReplyChannel(this.publishPackageChannel());
    proxy.afterPropertiesSet();
    return proxy;
}

接下来,CMS发布流附加到publishPackageItem通道,并根据拆分后的类型,路由到特定元素通道进行处理。分割页面后,只有特定的元素类型可能有订阅流程

@Inject
public CmsPublishFlow(@PublishPackageItemChannel final MessageChannel channelPublishPackageItem)
{
    this.channelPublishPackageItem = channelPublishPackageItem;
}

@Bean
@PublishPageChannel
MessageChannel channelPublishPage()
{
    return MessageChannels.direct().get();
}

@Bean
IntegrationFlow flowPublishContent()
{
    return flow -> flow
        .channel(this.channelPublishPackageItem)
        .filter(PackageEntry.class, p -> p.getEntry() instanceof Page)
        .transform(PackageEntry.class, PackageEntry::getEntry)
        .split(Page.class, this::traversePageElements)
        .<Content, String>route(Content::getType, mapping -> mapping
            .resolutionRequired(false)
            .subFlowMapping(PAGE, sf -> sf.channel(channelPublishPage()))
            .subFlowMapping(IMAGE, sf -> sf.channel(channelPublishAsset()))
            .defaultOutputToParentFlow());
    //.channel(IntegrationContextUtils.NULL_CHANNEL_BEAN_NAME);
}

最后,我的目标是订阅频道并相应地处理每个元素。我将此流程订阅到channelPublishPage。每个订阅者可以不同地处理该元素。

@Inject
@PublishPageChannel
private MessageChannel channelPublishPage;

@Bean
IntegrationFlow flowPublishPage()
{
    return flow -> flow
        .channel(this.channelPublishPage)
        .publishSubscribeChannel(c -> c
            .subscribe(s -> s
                .<Page>handle((p, h) -> this
                    .generatePage(p))));
}

1 个答案:

答案 0 :(得分:1)

我不知何故觉得问题在这里:

proxy.setDefaultRequestChannel(this.publishPackageChannel());
 proxy.setDefaultReplyChannel(this.publishPackageChannel());

请考虑不要对请求和等待回复使用相同的通道。这样你就会带来一些循环和非常意外的行为。