Java 使用 Lambda 进行跟踪会产生尴尬的行为

Java Shadowing with Lambdas producing awkward behavior

我将 DSL 和 Lambdas 与 Spring 集成库一起使用,运行 遇到了一个奇怪的问题。

我试图构建一个 IntegrationFlow,它会在换行符处拆分文件数据。当我将 lambda 表达式内联到构建器时,它工作正常:

return IntegrationFlows.from(this.inboundStreamingMessageSource())
        .transform(new StreamTransformer("UTF-8"))
        .split(s->s.applySequence(true).get().getT2().setDelimiters("\n"))

在上面的示例中,split 方法正在接收 SplitterEndpointSpec 的 Consumer。那时我将 lambda 分解到它自己的字段中以提高可读性:

return IntegrationFlows.from(this.inboundStreamingMessageSource())
        .transform(new StreamTransformer("UTF-8"))
        .split(NewlineSplitter)
        ...

final Consumer<SplitterEndpointSpec<DefaultMessageSplitter>> NewlineSplitter = 
    s -> s.applySequence(true).get().getT2().setDelimiters("\n");

但是,我得到一个堆栈跟踪异常 运行。目前它的:

org.springframework.messaging.MessageHandlingException: nested exception is java.lang.IllegalArgumentException: No candidate methods found for messages

另一次,我收到一个 Classcast 异常,指出类型 String.class 无法转换为 SplitterEndpointSpec。如果您查看我从中调用 splitIntegrationFlowDefinition 的 API 文档,您会发现该方法被严重遮蔽:大约有 12不同参数长度的变化。编译器是否误解了我正在调用的 split 版本?

我根本看不出是什么导致了这种行为,我不确定这是 Java 8 错误还是 Spring 集成实现的问题。我正在使用 spring-integration-dsl 1.2.3.RELEASE,由于在为它构建的另一个库中定义的依赖项,目前我可能坚持使用该版本。

首先你不需要练习 get().getT2().setDelimiters("\n") - SplitterEndpointSpec 上已经有一个 delimiters() 选项:

s.applySequence(true).delimiters("\n")

其次,它看起来更像是你使用的编译器的问题。刚刚测试了您的用例:

java version "1.8.0_172"
Java(TM) SE Runtime Environment (build 1.8.0_172-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.172-b11, mixed mode)

运行良好,没有任何抱怨和运行时错误。

另一方面,我使用最新的 Spring 集成。你呢?使用的是什么版本?