DSL-фильтр Spring Integration против RouteToRecipients с одним Recipient и DefaultOutputToParentFlow - PullRequest
3 голосов
/ 14 февраля 2020

Мне нужно перенаправить сообщение из моего родительского потока в новый поток, когда данная оценка возвращает false, но продолжить его в родительском потоке, когда эта оценка возвращает true. В настоящее время я смог успешно реализовать эту функцию с помощью метода Spring Integration DSL .filter() без каких-либо проблем. Однако мне кажется, что использование .filter() таким образом не подпадает под истинное намерение этого метода. Существует ли определенный тип маршрутизатора, который можно использовать для достижения этой же потребности? Необходимо ли перейти от этой .filter() реализации к реализации на основе маршрутизатора?

Учитывая приведенную ниже конфигурацию потока интеграции в качестве примера ...

@Bean
public IntegrationFlow flow() {
    return IntegrationFlows
            .from("inboundChannel")
            .filter(someService::someTrueFalseMethod, onFalseReturn -> onFalseReturn.discardChannel("otherFlowInboundChannel"))
            .handle(someService::someHandleMethod)
            .get();
}

@Bean
public IntegrationFlow otherFlow() {
    return IntegrationFlows
            .from("otherFlowInboundChannel")
            .handle(someOtherService::someOtherHandleMethod)
            .get();
}

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

@Bean
public IntegrationFlow flow() {
    return IntegrationFlows
            .from("inboundChannel"
            .routeToRecipients(router -> router
                .recipientMessageSelector("otherFlowInboundChannel", someService::someTrueFalseMethod)
                .defaultOutputToParentFlow()
            )
            .handle(someService::someHandleMethod)
            .get();
}

@Bean
public IntegrationFlow otherFlow() {
    return IntegrationFlows
            .from("otherFlowInboundChannel")
            .handle(someOtherService::someOtherHandleMethod)
            .get();
}

Даже с таким решением routeToRecipients, которое работает, действительно ли есть какое-либо Выгода, полученная между этим и внедрением фильтра выше?

1 Ответ

2 голосов
/ 14 февраля 2020

Ну, на самом деле речь идет не о Java методах DSL, а о том, как их использовать. Это действительно теория вокруг этих IE шаблонов.

Давайте сравним Filter и RecipientListRouter из EIP!

Фильтр - https://www.enterpriseintegrationpatterns.com/patterns/messaging/Filter.html:

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

Итак, технически filter не соответствует вашим ожиданиям, поскольку при разрешении false вы вроде отбрасываете сообщение. Однако для возможной обработки этих отброшенных сообщений Spring Integration предоставляет опцию discardChannel для инициирования подпотока отбрасывания. Таким образом, мы можем рассматривать это как if..else конструкция ...

Список получателей - https://www.enterpriseintegrationpatterns.com/patterns/messaging/RecipientList.html

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

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

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

recipientList - для более сложного сценария ios, когда селектор используется для любой произвольной оценки, а не просто логического типа и имеет возможность распределять одно и то же сообщение по нескольким выходным каналам. Поэтому я бы не рекомендовал это для этого простого true/false сценария.

Вы можете рассмотреть другой похожий шаблон:

Маршрутизатор на основе содержимого - https://www.enterpriseintegrationpatterns.com/patterns/messaging/ContentBasedRouter.html

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

Похоже, что это очень близко к тому, что вам нужно с true/false, и он не собирается злоупотреблять ошибками (отбрасываниями) для flow cotrol и не диктует нам список получателей. И у этого также есть тот defaultOutputToParentFlow(), когда вы хотели бы положиться на не отображенный результат.

ИМХО, я бы остановился на filter() - с его true/false logi c и discardChannel это действительно похоже на конкретную реализацию этого Content Based Router :-).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...