【问题标题】:Spring Integration: Recursive Flow?Spring 集成:递归流?
【发布时间】:2020-01-27 20:58:45
【问题描述】:

我是 Spring/Spring 集成的新手,无法理解如何正确实现允许可变数量的出站网关调用的流程。

问题:给定一个客户 ID,我进行一次出站网关呼叫以获取相关客户的列表。对于每个相关客户,然后我需要进行另一个出站网关呼叫。

我的初始方法:在第一次服务调用之后,我用接收到的相关客户 ID 填充一个队列,调用一个辅助方法来轮询队列,然后通过调用 outbound 继续流程网关再次执行下一个请求(仅当有客户离开时)。收到响应后,网关会调用相同的辅助方法来重复该过程。

如果队列为空,则使用标头将流路由到辅助方法中的 logAndReply(代码见下文)。

private IntegrationFlow helperMethod()
{
    return flow -> flow

        .transform(payload -> {
            currentCust = info.poll();
            return payload;
        })

        //check if there is another related-customer to process
        .handle(
                (payload, headers) -> MessageBuilder
                        .withPayload(payload)
                        .copyHeaders(headers)
                        .setHeader("relatedCustomerLeft", (null == currentCust ? Boolean.FALSE : Boolean.TRUE))
                        .build()
        )
        .route(("headers['relatedCustomerLeft']"), route -> route

                //if no more related-customers, end the flow
                .subFlowMapping(Boolean.FALSE,
                        subFlow -> subFlow
                            .logAndReply(LoggingHandler.Level.INFO, "end of base case")
                )
                //if there is a related customer, call the gateway
                .subFlowMapping(Boolean.TRUE,
                        subGateway()
                )
        );
}

这里,subGateway() 只是返回另一个处理出站服务调用的 IntegrationFlow。当我删除递归调用时,这个逻辑似乎有效。但是,包含递归调用会在启动时导致堆栈溢出错误。日志只是一遍又一遍地显示“使用 SOAP 1.1 协议创建 SAAJ 1.3 MessageFactory”,直到发生堆栈溢出。

"上下文初始化期间遇到异常 - 取消 刷新尝试: org.springframework.beans.factory.BeanCreationException:错误 创建文件中定义的名称为“getFlow”的bean [GetFlow.class]: bean初始化失败;嵌套异常是 java.lang.StackOverflowError"

我的问题是

  1. 为什么会发生堆栈溢出?
  2. 我尝试使用递归的方式是否可行?如何正确实施?
  3. 是否有更好的方法来进行可变数量的网关调用?有什么例子吗?

正如我所说,我还是新手,所以任何提示或资源也将不胜感激。

【问题讨论】:

    标签: java spring spring-integration


    【解决方案1】:

    首先,您没有展示如何创建该递归,其次,不清楚为什么在您的用例中需要递归。

    听起来您需要enrich()“获取相关客户列表”。 然后,您需要 split() 针对返回的客户列表为每个客户调用服务。在我看来,仅此而已!不需要任何递归。

    我也会考虑在split() 之前添加一个filter(),以确保列表不为空。或者route(),因为你已经...

    但仍然不清楚递归会在哪里弹出......

    【讨论】:

    • 递归是 subGateway() 在执行出站服务调用后调用 helperMethod() 的结果。我的想法是保存每个服务调用的响应,以便在考虑所有相关客户后构建最终响应消息。不过,我会尝试您的建议。谢谢!
    • 将结果保存在共享位置是不好的:其他一些进程可能会访问与其无关的数据。在消息头中保存中间数据真的很好。
    猜你喜欢
    • 1970-01-01
    • 2016-03-02
    • 2021-07-09
    • 1970-01-01
    • 2015-01-16
    • 2020-11-12
    • 2023-04-07
    • 2014-03-05
    • 2019-04-30
    相关资源
    最近更新 更多