@Configuration
@ImportResource("classpath:/filewriter-config.xml")
public class FileWriterIntegrationConfig { ... }
Хотя конфигурация на основе XML хорошо послужила Spring Integration, большинство разработчиков опасаются использовать XML. (И, как я уже сказал, я избегаю конфигурации через XML в этой книге.) Давайте отложим эти угловые скобки и обратим наше внимание на стиль конфигурации через Java в Spring Integration.
9.1.2 Настройка потоков интеграции через Java
Большинство современных приложений Spring отказались от конфигурации XML в пользу конфигурации Java. Фактически в приложениях Spring Boot конфигурация Java является естественным стилем, дополняющим автоконфигурацию. Поэтому, если вы добавляете поток интеграции в приложение Spring Boot, имеет смысл определить поток посредством Java.
В качестве примера того, как написать поток интеграции используя 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", //Объявляем transformer
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;
}
}
В Java конфигурации вы объявляете два bean-компонента: преобразователь (transformer) и обработчик сообщения для записи файла. Трансформатор является универсальным трансформатором. Поскольку GenericTransformer является функциональным интерфейсом, вы можете предоставить его реализацию в виде лямбды, которая вызывает toUpperCase() в тексте сообщения. Преобразователь bean аннотируется @Transformer, определяющим его как преобразователь в потоке интеграции, который принимает сообщения в канале с именем textInChannel и записывает сообщения в канал с именем fileWriterChannel.
Что касается bean для записи файлов, он помечается @ServiceActivator, чтобы указать, что он будет принимать сообщения от fileWriterChannel и передавать эти сообщения сервису, определенному экземпляром FileWritingMessageHandler. FileWritingMessageHandler - это обработчик сообщений, который записывает полезную нагрузку сообщения в файл в указанном каталоге, используя имя файла, указанное в заголовке file_name сообщения. Как и в примере с XML, FileWritingMessageHandler настроен на добавление в файл новой записи.
Уникальной особенностью конфигурации bean-компонента FileWritingMessageHandler является то, что существует вызов метода setExpectReply(false), который указывает, что активатору службы не следует ожидать ответный канал (канал, через который значение может быть возвращено вышестоящим компонентам в потоке). Если вы не вызываете setExpectReply(), для записи файла bean по умолчанию имеет значение true, и, хотя функция по-прежнему работает должным образом, вы увидите несколько ошибок, указывающих, что канал ответа не настроен.
Вы также заметите, что вам не нужно явно объявлять каналы. Каналы textInChannel и fileWriterChannel будут созданы автоматически, если бинов с этими именами не существует. Но если вам нужен больший контроль над конфигурацией каналов, вы можете явно создать их как bean-компоненты:
@Bean
public MessageChannel textInChannel() {
return new DirectChannel();
}
...
@Bean
public MessageChannel fileWriterChannel() {
return new DirectChannel();
}
Конфигурация посредством Java, возможно, проще для чтения и немного короче, и, безусловно, соответствует конфигурации “только Java”, о которой я рассказываю в этой книге. Но это можно сделать еще более упорядоченным с помощью стиля конфигурации Spring Integration Java DSL (предметно-ориентированного языка).
9.1.3 Использование конфигурации DSL Spring Integration
Давайте еще раз попробуем настроить поток интеграции записи файлов. На этот раз вы все равно настроите его через Java, но вы будете использовать Spring Integration Java DSL. Вместо объявления отдельного bean для каждого компонента в потоке, вы объявите один bean, который определяет весь поток.
Листинг 9.4. Предоставление свободного API для проектирования потоков интеграции
package sia5;
import java.io.File;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.dsl.IntegrationFlow;