java.util.function Interfaces Support

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

Starting with version 5.1, Spring Integration provides direct support for interfaces in the java.util.function package. All messaging endpoints, (Service Activator, Transformer, Filter, etc.) can now refer to Function (or Consumer) beans. The Messaging Annotations can be applied directly on these beans similar to regular MessageHandler definitions. For example if you have this Function bean definition:

@Configuration
public class FunctionConfiguration {

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

}

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

You can use it as a simple reference in an XML configuration file:

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

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

When we configure our flow with Messaging Annotations, the code is straightforward:

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

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

When the function returns an array, Collection (essentially, any Iterable), Stream or Reactor Flux, @Splitter can be used on such a bean to perform iteration over the result content.

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

The java.util.function.Consumer interface can be used for an <int:outbound-channel-adapter> or, together with the @ServiceActivator annotation, to perform the final step of a flow:

@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() 方法调用的目标类型。

Also, pay attention to the comment in the code snippet above: if you would like to deal with the whole message in your Function/Consumer you cannot use a lambda definition. Because of Java type erasure we cannot determine the target type for the apply()/accept() method call.

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

The java.util.function.Supplier interface can simply be used together with the @InboundChannelAdapter annotation, or as a ref in an <int:inbound-channel-adapter>:

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

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

With the Java DSL we just need to use a reference to the function bean in the endpoint definitions. Meanwhile, an implementation of the Supplier interface can be used as regular MessageSource definition:

@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 框架结合使用时,此功能支持非常有用,在这种情况下我们有功能目录,并且可以从集成流定义中引用其成员功能。

This function support is useful when used together with the Spring Cloud Function framework, where we have a function catalog and can refer to its member functions from an integration flow definition.