Service Activators and the .handle()
method
EIP 方法 handle()
的目标是调用任何 MessageHandler
实现或任何 POJO 的方法。另一个选择是使用 lambda 表达式定义 "`activity`”。因此,我们引入了一个泛型 GenericHandler<P>
函数接口。它的 handle
方法需要两个参数:P payload
和 MessageHeaders headers
(从版本 5.1 开始)。有了它,我们可以如下定义一个流程:
The .handle()
EIP method’s goal is to invoke any MessageHandler
implementation or any method on some POJO.
Another option is to define an “activity” by using lambda expressions.
Consequently, we introduced a generic GenericHandler<P>
functional interface.
Its handle
method requires two arguments: P payload
and MessageHeaders headers
(starting with version 5.1).
Having that, we can define a flow as follows:
@Bean
public IntegrationFlow myFlow() {
return IntegrationFlow.from("flow3Input")
.<Integer>handle((p, h) -> p * 2)
.get();
}
前面的示例将它接收的任何整数加倍。
The preceding example doubles any integer it receives.
但是,Spring Integration 的一个主要目标是通过从消息负载到消息处理器的目标参数的运行时类型转换实现 松散耦合
。由于 Java 不支持对 lambda 类进行泛型类型解析,因此我们为大多数 EIP 方法和 LambdaMessageProcessor
提供了一种变通方法,即一个额外的 payloadType
参数。这样做将繁重的转换工作委托给 Spring 的 ConversionService
,它使用提供给目标方法参数的 type
和所请求的消息。下面示例显示了 IntegrationFlow
的运行结果:
However, one main goal of Spring Integration is loose coupling
, through runtime type conversion from message payload to the target arguments of the message handler.
Since Java does not support generic type resolution for lambda classes, we introduced a workaround with an additional payloadType
argument for the most EIP methods and LambdaMessageProcessor
.
Doing so delegates the hard conversion work to Spring’s ConversionService
, which uses the provided type
and the requested message to target method arguments.
The following example shows what the resulting IntegrationFlow
might look like:
@Bean
public IntegrationFlow integerFlow() {
return IntegrationFlow.from("input")
.<byte[], String>transform(p - > new String(p, "UTF-8"))
.handle(Integer.class, (p, h) -> p * 2)
.get();
}
我们还可以在 ConversionService
中注册一些 BytesToIntegerConverter
以摆脱额外的 .transform()
:
We also can register some BytesToIntegerConverter
within ConversionService
to get rid of that additional .transform()
:
@Bean
@IntegrationConverter
public BytesToIntegerConverter bytesToIntegerConverter() {
return new BytesToIntegerConverter();
}
@Bean
public IntegrationFlow integerFlow() {
return IntegrationFlow.from("input")
.handle(Integer.class, (p, h) -> p * 2)
.get();
}
另见 xref:dsl/java-basics.adoc#java-dsl-class-cast[Lambdas And Message<?>
参数。
Also see Lambdas And Message<?>
Arguments.