Чтобы получить удовольствие от Spring Integration, вы создадите поток интеграции, который записывает данные в файловую систему. Для начала вам нужно добавить Spring Integration в ваш проект. Для Maven необходимы следующие зависимости:
Первая зависимость - это стартер Spring Boot для Spring Integration. Эта зависимость важна для разработки потока Spring Integration, независимо от того, с чем он будет интегрироваться. Как и все starter зависимости Spring Boot, он доступен в виде флажка в форме Initializr.
Вторая зависимость - для файла Spring Integration endpoint модуля. Этот модуль является одним из более двух десятков endpoint модулей, используемых для интеграции с внешними системами. Мы поговорим подробнее о endpoint модулях в разделе 9.2.9. Но на данный момент известно, что endpoint модуль файлов предлагает возможность загружать файлы из файловой системы в поток интеграции и / или записывать данные из потока на файловую систему.
Затем необходимо создать способ для приложения, чтобы отправить данные в поток интеграции, так что он может быть записан в файл. Для этого вы создадите интерфейс шлюза, например, показанный ниже.
Листинг 9.1 Интерфейс шлюза сообщений для преобразования вызовов методов в сообщения
package sia5;
import org.springframework.integration.annotation.MessagingGateway;
import org.springframework.integration.file.FileHeaders;
import org.springframework.messaging.handler.annotation.Header;
@MessagingGateway(defaultRequestChannel="textInChannel") //Объявляет шлюз сообщений
public interface FileWriterGateway {
void writeToFile(@Header(FileHeaders.FILENAME) String filename,String data); //Пишет в файл
}
Хотя это простой Java интерфейс, о FileWriterGateway можно многое сказать. Первое, что вы заметите, это то, что он аннотирован @MessagingGateway. Эта аннотация указывает Spring Integration на создание реализации этого интерфейса должно поисходить во время выполнения - подобно тому, как Spring Data автоматически генерирует реализации интерфейсов репозитория. Другие части кода будут использовать этот интерфейс, когда им нужно будет переписать файл.
Атрибут defaultRequestChannel @MessagingGateway указывает, что любые сообщения, полученные в результате вызова методов интерфейса, должны быть отправлены в данный канал сообщений. В этом случае вы заявляете, что любые сообщения, возникающие в результате вызова writeToFile(), должны отправляться на канал, имя которого textInChannel.
Что касается метода writeToFile(), он принимает имя файла в виде String и String, содержащий текст, который должен быть записан в файл. Что примечательно в сигнатуре этого метода, так это то, что параметр имени файла аннотирован @Header. В этом случае аннотация @Header указывает, что значение, переданное в filename, должно быть помещено в заголовок сообщения (указанный как FileHeaders.FILENAME, который разрешается в file_name), а не в полезную нагрузку сообщения. Значение параметра data, помещается в полезную нагрузку сообщения.
Теперь, когда у вас есть шлюз сообщений, вам нужно настроить интеграционный поток. Несмотря на то, что начальная зависимость Spring Integration, которую вы добавили в свою сборку, обеспечивает необходимую автоконфигурацию для Spring Integration, вы все равно должны написать дополнительные конфигурации, чтобы определить потоки, отвечающие потребностям приложения. Вот три варианта конфигурации для объявления потоков интеграции:
-XML конфигурация
-Java конфигурация
- Java конфигурация с DSL
Мы рассмотрим все три из этих стилей конфигурации для Spring Integration, начиная с устаревшей конфигурации XML.
9.1.1 Определение потоков интеграции через XML
Хотя я избегал использования конфигурации XML в этой книге, Spring Integration имеет долгую историю интеграционных потоков, определенных в XML. Поэтому я считаю, что мне стоит показать хотя бы один пример потока интеграции, определенного через XML. В следующем списке показано, как настроить пример потока через XML.
Листинг 9.2 Определение потоков интеграции через XML
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:int="http://www.springframework.org/schema/integration" xmlns:int-file="http://www.springframework.org/schema/integration/file" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd http://www.springframework.org/schema/integration/file http://www.springframework.org/schema/integration/file/springintegration-file.xsd"> input-channel="textInChannel" output-channel="fileWriterChannel" expression="payload.toUpperCase()" /> // Преобразование текста channel="fileWriterChannel" directory="/tmp/sia5/files" mode="APPEND" append-new-line="true" /> //Записывает текст в файл
Детализация XML в листинге 9.2:
Настаиваем канал с именем textInChannel. Это тот же канал что установлен для запроса FileWriterGateway. При вызове метода writeToFile() в FileWriterGateway, результирующее сообщение публикуется на этом канале.
Настроили преобразователь (transformer), который получает сообщения от textInChannel. Он использует выражение Spring Expression Language (SpEL) для вызова toUpperCase() в полезной нагрузке сообщения. Результат операции верхнего регистра затем публикуется в fileWriterChannel.
Настроили канал с именем fileWriterChannel. Этот канал служит проводником, который соединяет transformer с адаптером исходящего канала.
Наконец, настроили адаптер исходящего канала, используя пространство имен int-file. Это пространство имен XML предоставляется модулем Spring Integration для записи файлов. Он настроен так что получает сообщения от fileWriterChannel и записывает полезные данные сообщения в файл, имя которого указано в заголовке file_name сообщения в каталоге, указанном в атрибуте каталога. Если файл уже существует, в него будут добавлены новые данные, а не перезаписан.
Этот поток показан на рис. 9.1 с использованием графических элементов, стилизованных под Enterprise Integration Patterns.
Шлюз записи файлов - Текст в канале - Uppercase transformer - Канал записи файлов - Адаптер исходящего канала файла
Рисунок 9.1 Поток интеграции записи файлов
Если вы хотите использовать конфигурацию XML в приложении Spring Boot, вам необходимо импортировать XML как ресурс в приложение Spring. Самый простой способ сделать это - использовать аннотацию Spring @ImportResource в одном из классов конфигурации вашего приложения:
@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
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;
}