> For the complete documentation index, see [llms.txt](https://potoyang.gitbook.io/spring-in-action-v5/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://potoyang.gitbook.io/spring-in-action-v5/di-9-zhang-ji-cheng-spring/9.2-tan-suo-spring-integration/9.2.6-fu-wu-ji-huo-qi.md).

# 9.2.6 服务激活器

服务激活器从输入信道接收消息并发送这些消息给的 MessageHandler。Spring 集成提供了多种的 MessageHandler 实现开箱即用（PayloadTypeRouter 就是 MessageHandler 的实现），但你会经常需要提供一些定制实现充当服务激活。作为一个例子，下面的代码说明了如何声明的 MessageHandler bean，构成为一个服务激活器：

```java
@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：

```java
@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 配置式中的服务激活器：

```java
public IntegrationFlow someFlow() {
    return IntegrationFlows
        ...
        .handle(msg -> {
            System.out.println("Message payload: " + msg.getPayload());
        })
        .get();
}
```

在这种情况下，MessageHandler 是作为一个 lambda，但也可以将它作为一个参考方法甚至是一个类，它实现了 MessageHandler 接口。如果给它一个 lambda 或方法引用，要知道，它是接受一个消息作为参数。

类似地，如果服务激活器不是流的结束，handler() 可以写成接受 GenericHandler 参数。从之前应用订单存储服务激活器来看，可以使用 Java DSL 对流程进行配置：

```java
public IntegrationFlow orderFlow(OrderRepository orderRepo) {
    return IntegrationFlows
        ...
        .<Order>handle((payload, headers) -> {
            return orderRepo.save(payload);
        })
        ...
        .get();
}
```

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