Перейти к основному содержимому

Введение в интеграцию Spring

· 7 мин. чтения

1. Введение

В этой статье будут представлены основные концепции Spring Integration в основном на небольших практических примерах.

Spring Integration предоставляет множество мощных компонентов, которые могут значительно улучшить взаимосвязь систем и процессов в архитектуре предприятия.

Он воплощает в себе некоторые из лучших и самых популярных шаблонов проектирования, помогая разработчикам избегать создания собственных шаблонов.

Мы рассмотрим конкретные потребности, которые эта библиотека заполняет в корпоративном приложении, и почему она предпочтительнее некоторых ее альтернатив. Мы также рассмотрим некоторые доступные инструменты для дальнейшего упрощения разработки приложений на основе Spring Integration.

2. Настройка

<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-core</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-file</artifactId>
<version>4.3.5.RELEASE</version>
</dependency>

Вы можете загрузить последние версии Spring Integration Core и Spring Integration File Support с сайта Maven Central.

3. Шаблон обмена сообщениями

Одним из основных шаблонов в этой библиотеке является обмен сообщениями. Шаблон сосредоточен вокруг сообщений — дискретных полезных нагрузок данных, которые перемещаются из исходной системы или процесса в одну или несколько систем или процессов по заранее определенным каналам.

Исторически шаблон возник как наиболее гибкий способ интеграции нескольких разрозненных систем таким образом, чтобы:

  • Почти полностью разделяет системы, участвующие в интеграции
  • Позволяет системам-участникам интеграции быть полностью независимыми друг от друга относительно базовых протоколов, форматирования или других деталей реализации.
  • Поощряет разработку и повторное использование компонентов, участвующих в интеграции

4. Интеграция обмена сообщениями в действии****

Давайте рассмотрим базовый пример , который копирует видеофайл MPEG из указанной папки в другую настроенную папку:

@Configuration
@EnableIntegration
public class BasicIntegrationConfig{
public String INPUT_DIR = "the_source_dir";
public String OUTPUT_DIR = "the_dest_dir";
public String FILE_PATTERN = "*.mpeg";

@Bean
public MessageChannel fileChannel() {
return new DirectChannel();
}

@Bean
@InboundChannelAdapter(value = "fileChannel", poller = @Poller(fixedDelay = "1000"))
public MessageSource<File> fileReadingMessageSource() {
FileReadingMessageSource sourceReader= new FileReadingMessageSource();
sourceReader.setDirectory(new File(INPUT_DIR));
sourceReader.setFilter(new SimplePatternFileListFilter(FILE_PATTERN));
return sourceReader;
}

@Bean
@ServiceActivator(inputChannel= "fileChannel")
public MessageHandler fileWritingMessageHandler() {
FileWritingMessageHandler handler = new FileWritingMessageHandler(new File(OUTPUT_DIR));
handler.setFileExistsMode(FileExistsMode.REPLACE);
handler.setExpectReply(false);
return handler;
}
}

Приведенный выше код настраивает активатор службы, канал интеграции и адаптер входящего канала.

Вскоре мы более подробно рассмотрим каждый из этих типов компонентов. Аннотация @EnableIntegration обозначает этот класс как конфигурацию Spring Integration.

Давайте начнем наш контекст приложения Spring Integration:

public static void main(String... args) {
AbstractApplicationContext context
= new AnnotationConfigApplicationContext(BasicIntegrationConfig.class);
context.registerShutdownHook();

Scanner scanner = new Scanner(System.in);
System.out.print("Please enter q and press <enter> to exit the program: ");

while (true) {
String input = scanner.nextLine();
if("q".equals(input.trim())) {
break;
}
}
System.exit(0);
}

Основной метод выше запускает контекст интеграции; он также принимает ввод символа « q » из командной строки для выхода из программы. Разберем компоненты подробнее.

5. Компоненты интеграции Spring****

5.1. Сообщение

Интерфейс org.springframework.integration.Message определяет Spring Message: единицу передачи данных в контексте Spring Integration.

public interface Message<T> {
T getPayload();
MessageHeaders getHeaders();
}

Он определяет средства доступа к двум ключевым элементам:

  • Заголовки сообщений, по сути, контейнер ключ-значение, который можно использовать для передачи метаданных, как определено в классе org.springframework.integration.MessageHeaders.
  • Полезная нагрузка сообщения, представляющая собой фактические данные, которые представляют ценность для передачи — в нашем случае видеофайл является полезной нагрузкой.

5.2. Канал

Канал в Spring Integration (и, конечно же, EAI) — это основная сантехника в интеграционной архитектуре. Это канал, по которому сообщения передаются из одной системы в другую.

Вы можете думать об этом как о буквальном канале, через который интегрированная система или процесс может передавать сообщения другим системам (или получать сообщения от них).

Каналы в Spring Integration бывают разных видов, в зависимости от ваших потребностей. Они в значительной степени настраиваются и могут использоваться «из коробки», без какого-либо пользовательского кода, но если у вас есть особые потребности, доступна надежная структура.

Каналы точка-точка (P2P) используются для установления линий связи 1-к-1 между системами или компонентами. Один компонент публикует сообщение в канале, чтобы другой мог его подобрать. На каждом конце канала может быть только один компонент.

Как мы видели, настроить канал так же просто, как вернуть экземпляр DirectChannel :

@Bean
public MessageChannel fileChannel1() {
return new DirectChannel();
}

@Bean
public MessageChannel fileChannel2() {
return new DirectChannel();
}

@Bean
public MessageChannel fileChannel3() {
return new DirectChannel();
}

Здесь мы определили три отдельных канала, каждый из которых идентифицируется по имени их соответствующих методов получения.

Каналы публикации-подписки (Pub-Sub) используются для установления линии связи «один ко многим» между системами или компонентами. Это позволит нам публиковать все 3 прямых канала, которые мы создали ранее.

Итак, следуя нашему примеру, мы можем заменить канал P2P каналом pub-sub:

@Bean
public MessageChannel pubSubFileChannel() {
return new PublishSubscribeChannel();
}

@Bean
@InboundChannelAdapter(value = "pubSubFileChannel", poller = @Poller(fixedDelay = "1000"))
public MessageSource<File> fileReadingMessageSource() {
FileReadingMessageSource sourceReader = new FileReadingMessageSource();
sourceReader.setDirectory(new File(INPUT_DIR));
sourceReader.setFilter(new SimplePatternFileListFilter(FILE_PATTERN));
return sourceReader;
}

Теперь мы преобразовали адаптер входящего канала для публикации в канал Pub-Sub. Это позволит нам отправлять файлы, которые считываются из исходной папки, в несколько мест назначения.

5.3. Мост

Мост в Spring Integration используется для соединения двух каналов сообщений или адаптеров, если по какой-либо причине они не могут подключиться напрямую.

В нашем случае мы можем использовать мост для подключения нашего канала Pub-Sub к трем различным каналам P2P (поскольку каналы P2P и Pub-Sub не могут быть подключены напрямую):

@Bean
@BridgeFrom(value = "pubSubFileChannel")
public MessageChannel fileChannel1() {
return new DirectChannel();
}

@Bean
@BridgeFrom(value = "pubSubFileChannel")
public MessageChannel fileChannel2() {
return new DirectChannel();
}

@Bean
@BridgeFrom(value = "pubSubFileChannel")
public MessageChannel fileChannel3() {
return new DirectChannel();
}

Приведенная выше конфигурация bean-компонента теперь соединяет pubSubFileChannel с тремя каналами P2P. Аннотация @BridgeFrom определяет мост и может применяться к любому количеству каналов, которым необходимо подписаться на канал Pub-Sub.

Мы можем прочитать приведенный выше код как «создать мост из pubSubFileChannel в fileChannel1, fileChannel2 и fileChannel3 , чтобы сообщения из pubSubFileChannel можно было передавать по всем трем каналам одновременно».

5.4. Активатор услуги

Активатор службы — это любой POJO, который определяет аннотацию @ServiceActivator для данного метода. Это позволяет нам выполнять любой метод в нашем POJO, когда сообщение получено из входящего канала, и позволяет нам писать сообщения во внешний канал.

В нашем примере наш сервисный активатор получает файл из настроенного канала ввода и записывает его в настроенную папку.

5.5. Адаптер

Адаптер — это компонент, основанный на шаблоне корпоративной интеграции, который позволяет «подключаться» к системе или источнику данных. Это почти буквально адаптер, который мы знаем по подключению к настенной розетке или электронному устройству.

Это позволяет повторно использовать подключение к другим системам «черного ящика», таким как базы данных, FTP-серверы и системы обмена сообщениями, такие как JMS, AMQP, и социальные сети, такие как Twitter. Повсеместная необходимость подключения к этим системам означает, что адаптеры очень портативны и многоразовые (на самом деле существует небольшой каталог адаптеров , находящихся в свободном доступе и готовых к использованию кем угодно).

Адаптеры делятся на две большие категории — входящие и исходящие.

Давайте рассмотрим эти категории в контексте адаптеров, используемых в нашем примерном сценарии:

Входящие адаптеры , как мы видели, используются для доставки сообщений из внешней системы (в данном случае из каталога файловой системы).

Наша конфигурация входящего адаптера состоит из:

  • Аннотация @InboundChannelAdapter , помечающая конфигурацию bean-компонента как адаптер — мы настраиваем канал, на который адаптер будет передавать свои сообщения (в нашем случае файл MPEG), и poller , компонент, который помогает адаптеру опрашивать настроенную папку на указанный интервал
  • Стандартный класс конфигурации Java Spring, который возвращает FileReadingMessageSource, реализацию класса Spring Integration, которая обрабатывает опрос файловой системы.

Исходящие адаптеры используются для отправки сообщений наружу. Spring Integration поддерживает большое количество готовых адаптеров для различных распространенных случаев использования.

6. Заключение

Мы рассмотрели базовый вариант использования Spring Integration, демонстрирующий конфигурацию библиотеки на основе Java и возможность повторного использования доступных компонентов.

Код Spring Integration можно развернуть как отдельный проект в JavaSE, а также как часть чего-то большего в среде Jakarta EE. Хотя он не конкурирует напрямую с другими ориентированными на EAI продуктами и шаблонами, такими как корпоративные сервисные шины (ESB), он представляет собой жизнеспособную и легкую альтернативу решению многих из тех же проблем, для решения которых были созданы ESB.

Исходный код этой статьи вы можете найти в проекте Github .