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,否则会得到这表明有没有指定输出通道的错误。