Шаг пользовательской обработки Spring интеграции

Мне нужно ввести этап обработки в весеннюю интеграцию примерно так:

import org.springframework.messaging.Message;

public class SomeDocumentProcessingStep {

    public Message<MyDocument> process(Message<MyDocument> myMessage) {
        // do some manipulations with message like providing new headers;
        return resultingMessage;
    }
}

Вопрос в том, как включить такой этап обработки в конфигурацию интеграции Spring? У меня что-то вроде этого:

<int:chain input-channel = "someInput" output-channel = "someOutput">
    <!--Here I want to use my processing step class -->
    <!--Chain contains other processing steps like transformations -->
</int:chain>

Один из способов сделать это, если с service-activator, но тогда мне нужно отправить новое сообщение вручную из моей службы. Что-то вроде этого:

public class SomeService {
    private final MessageChannel outputChannel;
    private final MessagingTemplate template;
    // constructor ommited
    public void distribute(Message<MyDocument> message) {
        // do my manipulations
        template.send(outputChannel, resultingMessage);
    }
}

И настройте его примерно так:

<int:service-activator input-channel = "someInput" ref = "someService" method = "distribute"/>

Но у меня такое ощущение, что это неправильный подход. Есть ли лучший способ сделать это внутри цепочки интеграции? Мне нужен этот настраиваемый шаг обработки, который будет в середине обработки сообщения. Для меня использования <int:header-enricher> недостаточно, так как он позволяет создавать заголовки один за другим. Я хочу делать это в одном классе.

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
133
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы идете правильным путем с <service-activator> внутри chain. Только проблема, с которой вы столкнулись, в том, что вам не нужен этот канал на service-activator. Это цепочка - единая составная конечная точка для набора шагов. Итак, вам все равно нужно каким-то образом отправить сообщение в этот someInput, но это уже будет точкой входа для всей цепочки. Пожалуйста, прочтите документацию по теме: https://docs.spring.io/spring-integration/docs/5.0.4.RELEASE/reference/html/messaging-routing-chapter.html#chain

но результат service-activator не будет передан на some-output цепочки. Но вы даете мне идею добавить собственный Transformer в цепочку.

Izbassar Tolegen 08.05.2018 14:49

Этот some-output получает сообщение от последнего компонента в цепочке. Не уверен, что вы думаете о цепочке, что вы относитесь к ней по-другому ...

Artem Bilan 08.05.2018 15:22
some-output получит неизмененное сообщение. То же, что было до ввода service-activator. Мне нужно доставить измененное сообщение на some-output (resultingMessage из класса service-activator). Этого не произойдет, если я не отправлю его вручную с service-activator. И я не могу изменить сообщение в service-activator, так как сообщение неизменяемо. Если я помещу свой класс service-activator в цепочку, я получу 2 сообщения в some-output: 1 немодифицированное и 1 от ручного шага внутри service-activator. Мне нужен только 1.
Izbassar Tolegen 08.05.2018 15:27

Чтобы прояснить: сообщение идет на some-input -> Мне нужны мои пользовательские модификации (и стандартных заголовков недостаточно) -> Мне нужно, чтобы это измененное сообщение было доставлено в some-output. Я могу сделать это вручную с помощью service-activator (получить от some-input, затем отправить сообщение вручную на some-output). Итак, вопрос в том, существует ли более ясный способ весенней интеграции или нет. Приносим извинения за путаницу, если вопрос не ясен.

Izbassar Tolegen 08.05.2018 15:30

ОК! Теперь непонятно, в чем тогда задача. Метод активатора службы может вернуть любое сообщение, которое перейдет к следующему шагу в вашем потоке. Итак, почему бы просто не создать новое сообщение и не вернуть его из служебного метода. Похоже, здесь все в лабиринте: я не могу скомпилировать задачу.

Artem Bilan 08.05.2018 15:33

Итак, если я сделаю свой метод на service-activator для возврата нового экземпляра, который автоматически перейдет к следующему шагу в цепочке?

Izbassar Tolegen 08.05.2018 15:41

Верный. В этом суть потоковой передачи с компонентами интеграции. Самая простая модель для этого - java.util.function.Function.andThen().

Artem Bilan 08.05.2018 15:43

Другие вопросы по теме