9.2.6 服务激活器

服务激活器从输入信道接收消息并发送这些消息给的 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="completeOrder")
public GenericHandler<Order> 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
        ...
        .<Order>handle((payload, headers) -> {
            return orderRepo.save(payload);
        })
        ...
        .get();
}

当利用 GenericHandler 时,lambda 表达式或方法参考接受该消息的有效载荷和报头作为参数。另外,如果选择在一个流程的结束使用 GenericHandler,需要返回 null,否则会得到这表明有没有指定输出通道的错误。

最后更新于