Spring Integration DSL: настроить обработчик, который обрабатывает, только когда аргумент совпадает

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

Например: в следующем коде, если полезная нагрузка MyObject2, Spring вызовет ClassCastException в handleMessage. Вместо этого я хочу обойти handleMessage и подхватить handleMessage2.

@Bean
public IntegrationFlow myFlow() {
  return IntegrationFlows
                .from("myChannel")
                .handle(this::handleMessage)
                .handle(this::handleMessage2)
                ...
}

public MyObject2 handleMessage(MyObject o, Map headers){
...
}

public MyObject2 handleMessage(MyObject2 o, Map headers){
...
}

person hummingV    schedule 21.09.2017    source источник


Ответы (1)


За .handle() стоит уловка, заключающаяся в том, что он выбирает все подходящие методы для обработки сообщений на этапе инициализации, а затем во время выполнения выполняет функцию:

HandlerMethod candidate = this.findHandlerMethodForParameters(parameters);

Итак, чтобы иметь возможность выбрать тот или иной метод на основе payload из сообщения запроса, вы должны сказать .handle() для этого:

  return IntegrationFlows
            .from("myChannel")
            .handle(this)
            ...

Конечно, в этом случае было бы лучше переместить этот метод в отдельный класс обслуживания, чтобы избежать дополнительного выбора методов из этого @Configuration класса.

person Artem Bilan    schedule 21.09.2017
comment
Это выглядит потрясающе, но я считаю, что такие методы автоматического выбора подвержены ошибкам. например: в моем примере, если приходит сообщение типа MyObject, я бы хотел, чтобы и handleMessage, и handleMessage2 запускались в указанном порядке. Я считаю, что ваш метод будет запускать только handleMessage, а не handleMessage2. - person hummingV; 21.09.2017
comment
Что ж, оба метода - это определенно отдельная история. Это выходит за рамки интеграции Spring. Хотя мы можем предоставить вам решение: publish-subscribe или recipient-list-router. Но опять же: это заслуживает отдельного ТАК-вопроса. - person Artem Bilan; 21.09.2017
comment
Как вы думаете, почему это выходит за рамки интеграции Spring? Фактический вариант использования для меня - обработка маркеров FileSplitter SOF, EOF. Обычные обработчики сообщений не должны заботиться о них, в отличие от агрегаторов и других обработчиков файлов. Итак, я хочу, чтобы эти маркеры SOF и EOF просто проходили через поток, не имея в потоке всех моих методов-обработчиков для проверки типов. - person hummingV; 22.09.2017
comment
Пожалуйста, сформируйте новый вопрос SO с дополнительной информацией для исследования. Не вижу, как это соотносится с текущим. - person Artem Bilan; 22.09.2017
comment
Я полностью думаю, что они связаны, но хорошо, я отправлю еще один более конкретный вопрос. - person hummingV; 22.09.2017
comment
Что ж, одна уловка может быть похожа на то, чтобы иметь там еще один метод, похожий на Object handleOthers(Object payload) { return payload; }. Итак, эти SOF,EOF будут обработаны здесь. Но то, что вы хотите, недоступно в готовом виде. Только вы можете сформировать свой собственный компонент по этому вопросу. - person Artem Bilan; 22.09.2017
comment
Спасибо, в любом случае, вот новый вопрос, если вам все еще интересно. stackoverflow.com/questions/46353317/ - person hummingV; 22.09.2017
comment
Хорошо, посмотрю в последнее время. Теперь мне интересно, закончили ли мы здесь, и моего ответа достаточно, чтобы принять его. - person Artem Bilan; 22.09.2017