10.2.6 服务激活器
服务激活器从输入信道接收消息并发送这些消息给的 MessageHandler,如图 10.7。

图 10.7 服务激活器在收到消息时通过 MessageHandler 调用某些服务。
Spring 集成提供了多种的 MessageHandler 实现开箱即用(PayloadTypeRouter 就是 MessageHandler 的实现),但您会经常需要提供一些定制实现充当服务激活。作为一个例子,下面的代码说明了如何声明的 MessageHandler bean,构成为一个服务激活器:
@Bean
@ServiceActivator(inputChannel="someChannel")
public MessageHandler sysoutHandler() {
return message -> {
System.out.println("Message payload: " + message.getPayload());
};
}
通过 @ServiceActivator 注解 bean,将其指定为一个服务激活器,从名为 someChannel 的信道处理消息。至于 MessageHandler 本身,它是通过一个 lambda 实现。虽然这是一个简单的 MessageHandler,但当收到消息时,它会将有效载荷输出到标准输出。
另外,可以声明一个服务激活器,用于在返回一个新的有效载荷之前处理传入的消息。在这种情况下,这个 bean 应该是一个 GenericHandler 而非 MessageHandler:
@Bean
@ServiceActivator(inputChannel="orderChannel",
outputChannel="completeChannel")
public GenericHandler<EmailOrder> orderHandler(
OrderRepository orderRepo) {
return (payload, headers) -> {
return orderRepo.save(payload);
};
}
在这种情况下,服务激活器是一个 GenericHandler,其中的有效载荷为 Order 类型。当订单到达,它是通过 repository 进行保存;保存 Order 后产生的结果被发送到名称为 completeChannel 的输出通道。
注意,GenericHandler 不仅给出了有效载荷,还包括消息头(即使本示例未使用头信息)。同时也可以通过传递 MessageHandler 或 GenericHandler 去调用在流定义中的 handler() 方法,在 Java DSL 配置中使用服务激活器:
public IntegrationFlow someFlow() {
return IntegrationFlows
...
.handle(msg -> {
System.out.println("Message payload: " + msg.getPayload());
})
.get();
}
在这种情况下,MessageHandler 是作为一个 lambda,但也可以将它作为一个参考方法甚至是一个类,它实现了 MessageHandler 接口。如果给它一个 lambda 或方法引用,要知道,它是接受一个消息作为参数。
类似地,如果服务激活器不是流的结束,handler() 可以写成接受 GenericHandler 参数。从之前应用订单存储服务激活器来看,可以使用 Java DSL 对流程进行配置:
public IntegrationFlow orderFlow(OrderRepository orderRepo) {
return IntegrationFlows
...
.<EmailOrder>handle((payload, headers) -> {
return orderRepo.save(payload);
})
...
.get();
}
当使用 GenericHandler 时,lambda 表达式或方法引用会接收消息的有效载荷和报头作为参数。另外,如果选择在流程末尾使用 GenericHandler,必须返回 null,否则会收到"未指定输出通道"的错误。