java.util.function Interfaces Support

从 5.1 版开始,Spring 集成直接支持 java.util.function`包中的接口。所有消息传递终结点(服务激活器、变形器、过滤器等)现在都可以引用 `Function(或 Consumer)bean。Messaging Annotations可以直接用于这些 bean,类似于常规 `MessageHandler`定义。例如,如果您有此 `Function`bean 定义:

@Configuration
public class FunctionConfiguration {

    @Bean
    public Function<String, String> functionAsService() {
        return String::toUpperCase;
    }

}

您可以在 XML 配置文件中将其用作简单引用:

<service-activator input-channel="processorViaFunctionChannel" ref="functionAsService"/>

当我们使用消息传递注释配置我们的流时,代码很简单:

@Bean
@Transformer(inputChannel = "functionServiceChannel")
public Function<String, String> functionAsService() {
    return String::toUpperCase;
}

当函数返回数组、Collection(基本上是任何 Iterable)、Stream 或 Reactor Flux 时,可以在此类 Bean 上使用 @Splitter 来对结果内容进行迭代。

java.util.function.Consumer 接口可用于 <int:outbound-channel-adapter>,也可以与 @ServiceActivator 注释一起用于执行流的最后一步:

@Bean
@ServiceActivator(inputChannel = "messageConsumerServiceChannel")
public Consumer<Message<?>> messageConsumerAsService() {
    // Has to be an anonymous class for proper type inference
    return new Consumer<Message<?>>() {

        @Override
        public void accept(Message<?> e) {
            collector().add(e);
        }

    };
}

另外,请注意上面代码段中的注释:如果您希望在 Function/Consumer 中处理整个消息,则不能使用 Lambda 定义。由于 Java 类型擦除,我们无法确定 apply()/accept() 方法调用的目标类型。

java.util.function.Supplier 接口可以与 @InboundChannelAdapter 注释一起使用,也可以作为 <int:inbound-channel-adapter> 中的 ref

@Bean
@InboundChannelAdapter(value = "inputChannel", poller = @Poller(fixedDelay = "1000"))
public Supplier<String> pojoSupplier() {
    return () -> "foo";
}

只要在端点定义中使用指向函数 bean 的引用,我们就可以使用 Java DSL。与此同时,Supplier 接口的实现可以用作常规的 MessageSource 定义:

@Bean
public Function<String, String> toUpperCaseFunction() {
    return String::toUpperCase;
}

@Bean
public Supplier<String> stringSupplier() {
    return () -> "foo";
}

@Bean
public IntegrationFlow supplierFlow() {
    return IntegrationFlow.from(stringSupplier())
                .transform(toUpperCaseFunction())
                .channel("suppliedChannel")
                .get();
}

在与 Spring Cloud Function 框架结合使用时,此功能支持非常有用,在这种情况下我们有功能目录,并且可以从集成流定义中引用其成员功能。