# 9.1.2 在 Java 中配置集成流

大多数现代 Spring 应用程序都避开了 XML 配置，而采用了 Java 配置。实际上，在 Spring Boot 应用程序中，Java 配置是自动配置的自然补充。因此，如果要将集成流添加到 Spring Boot 应用程序中，那么在 Java 中定义该流是很有意义的。

作为如何使用 Java 配置编写集成流的示例，请查看下面的程序清单。这显示了与以前相同的文件编写集成流，但这次是用 Java 编写的。

{% code title="程序清单 9.3 使用 Java 配置定义集成流" %}

```java
package sia5;
​
import java.io.File;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.annotation.Transformer;
import org.springframework.integration.file.FileWritingMessageHandler;
import org.springframework.integration.file.support.FileExistsMode;
import org.springframework.integration.transformer.GenericTransformer;
​
@Configuration
public class FileWriterIntegrationConfig {
    
    @Bean
    @Transformer(inputChannel="textInChannel", outputChannel="fileWriterChannel")
    public GenericTransformer<String, String> upperCaseTransformer() {
        return text -> text.toUpperCase();
    }
    
    @Bean
    @ServiceActivator(inputChannel="fileWriterChannel")
    public FileWritingMessageHandler fileWriter() {
        FileWritingMessageHandler handler = 
            new FileWritingMessageHandler(new File("/tmp/sia5/files"));
        handler.setExpectReply(false);
        handler.setFileExistsMode(FileExistsMode.APPEND);
        handler.setAppendNewLine(true);
        return handler;
    }
}
```

{% endcode %}

使用 Java 配置，可以声明两个 bean：一个转换器和一个文件写入消息处理程序。这里转换器是 GenericTransformer。因为 GenericTransformer 是一个函数接口，所以能够以 lambda 的形式提供在消息文本上调用 toUpperCase() 的实现。转换器的 bean使用 @Transformer 进行注解，并将其指定为集成流中的转换器，该转换器接收名为 textInChannel 的通道上的消息，并将消息写入名为 fileWriterChannel 的通道。

至于文件写入 bean，它使用 @ServiceActivator 进行了注解，以指示它将接受来自 fileWriterChannel 的消息，并将这些消息传递给由 FileWritingMessageHandler 实例定义的服务。FileWritingMessageHandler 是一个消息处理程序，它使用消息的 file\_name 头中指定的文件名将消息有效负载写入指定目录中的文件。与 XML 示例一样，将 FileWritingMessageHandler 配置为用换行符附加到文件中。

FileWritingMessageHandler bean 配置的一个独特之处是调用 setExpectReply(false) 来指示服务激活器不应该期望应答通道（通过该通道可以将值返回到流中的上游组件）。如果不调用 setExpectReply()，则文件写入 bean 默认为 true，尽管管道仍按预期工作，但将看到记录了一些错误，说明没有配置应答通道。

还会看到不需要显式地声明通道。如果不存在具有这些名称的 bean，就会自动创建 textInChannel 和 fileWriterChannel 通道。但是，如果希望对通道的配置方式有更多的控制，可以像这样显式地将它们构造为 bean：

```java
@Bean
public MessageChannel textInChannel() {
    return new DirectChannel();
}
...
@Bean
public MessageChannel fileWriterChannel() {
    return new DirectChannel();
}
```

可以说，Java 配置选项更易于阅读，也更简洁，而且与我在本书中所追求的纯 Java 配置完全一致。但是，通过 Spring Integration 的 Java DSL（领域特定语言）配置风格，它可以变得更加精简。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://potoyang.gitbook.io/spring-in-action-v5/di-9-zhang-ji-cheng-spring/9.1-sheng-ming-jian-dan-de-ji-cheng-liu/9.1.2-zai-java-zhong-pei-zhi-ji-cheng-liu.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
