Выбрать главу

Рисунок 9.8 Сервисные шлюзы - это интерфейсы, через которые приложение может отправлять сообщения в интеграционный поток.

Вы уже видели пример шлюза сообщений со шлюзом FileWriterGateway. FileWriterGateway был односторонним шлюзом с методом, принимающим String для записи в файл, возвращая void.  Примерно так же легко написать двусторонний шлюз. При написании интерфейса шлюза убедитесь, что метод возвращает некоторое значение для публикации в потоке интеграции.

В качестве примера представьте себе шлюз, который находится в простом интеграционном потоке, который принимает String и переводит данную строку в верхний регистр.  Интерфейс шлюза может выглядеть примерно так:

package com.example.demo;

import org.springframework.integration.annotation.MessagingGateway;

import org.springframework.stereotype.Component;

@Component

@MessagingGateway(defaultRequestChannel="inChannel", 

        defaultReplyChannel="outChannel")

public interface UpperCaseGateway {

    String uppercase(String in);

}

Что удивительно в этом интерфейсе, так это то, что его не нужно реализовывать. Spring Integration автоматически предоставляет реализацию во время выполнения, которая отправляет и получает данные по указанным каналам.

При вызове метода uppercase() данная String публикуется в потоке интеграции в канал с именем inChannel.  И, независимо от того, как определяется поток или что он делает, когда данные поступают в канал с именем outChannel, он возвращается из метода верхнего uppercase().

Что касается потока интеграции в верхнем регистре, то это упрощенный процесс интеграции с единственным шагом преобразования String в верхний регистр. Опишем в конфигурации Java DSL:

@Bean

public IntegrationFlow uppercaseFlow() {

    return IntegrationFlows

        .from("inChannel")

        .<String, String> transform(s -> s.toUpperCase())

        .channel("outChannel")

        .get();

}

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

9.2.8 Канальные адаптеры

Канальные адаптеры представляют точки входа и выхода потока интеграции. Данные входят в поток интеграции через адаптер входящего канала и выходят из потока интеграции через адаптер исходящего канала. Это показано на рисунке 9.9.

Рис. 9.9. Адаптеры канала - это точки входа и выхода потока интеграции.

Адаптеры входящего канала могут принимать различные формы в зависимости от источника данных, вводимых в поток. Например, вы можете объявить адаптер входящего канала, который вводит инкрементные числа из AtomicInteger в поток. При использовании Java конфигурации это может выглядеть так:

@Bean

@InboundChannelAdapter(

    poller=@Poller(fixedRate="1000"), channel="numberChannel")

public MessageSource<Integer> numberSource(AtomicInteger source) {

    return () -> {

        return new GenericMessage<>(source.getAndIncrement());

    };

}

Этот @Bean метод объявляет компонент адаптера входящего канала, который в соответствии с аннотацией @InboundChannelAdapter отправляет число из введенного AtomicInteger в канал с именем numberChannel каждые 1 секунду (или 1000 мс).

Принимая во внимание, что @InboundChannelAdapter указывает адаптер входящего канала при использовании конфигурации Java, метод from() - это то, как это делается при использовании Java DSL для определения потока интеграции. В следующем фрагменте определения потока показан аналогичный адаптер входящего канала, определенный в Java DSL:

@Bean

public IntegrationFlow someFlow(AtomicInteger integerSource) {

    return IntegrationFlows

        .from(integerSource, "getAndIncrement", c -> c.poller(Pollers.fixedRate(1000)))

        …

        .get();

}

Часто адаптеры каналов предоставляются одним из множества модулей конечной точки Spring Integration. Предположим, например, что вам нужен адаптер входящего канала, который отслеживает указанный каталог и отправляет любые файлы, которые записываются в этот каталог, как сообщения в канал с именем file-channel. Следующая конфигурация Java использует FileReadingMessageSource из модуля Spring Integration’s file endpoint для достижения этой цели:

@Bean

@InboundChannelAdapter(channel="file-channel", 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;

}

При записи эквивалентного адаптера входящего канала для чтения файлов в Java DSL метод inboundAdapter() из класса Files выполняет то же самое. Адаптер внешнего канала - это конец строки для процесса интеграции, передающий окончательное сообщение приложению или какой-либо другой системе: