Spring Integration DSL Одно и то же сообщение для обоих каналов

У нас есть требование, когда мне нужно, чтобы одно и то же сообщение (полезная нагрузка) обрабатывалось в двух разных каналах. У нас сложилось впечатление, что использование PubliSHSubscribe Channel поможет нам справиться с этим, сделав копию сообщения на оба канала. Однако мы полагали, что каждый канал выполнялся один за другим, и если мы вносим какие-либо изменения в полезную нагрузку в одном канале, это также влияет на полезную нагрузку другого канала.

@Bean
public IntegrationFlow bean1() {
    return IntegrationFlows
            .from("Channel1")
            .handle(MyMessage.class, (payload, header) -> obj1.method1(payload))
            .channel(MessageChannels.publishSubscribe("subscribableChannel").get())
            .get();
}


@Bean
public IntegrationFlow bean21() {
    return IntegrationFlows
            .from("subscribableChannel")
            .handle(MyMessage.class, (payload, header) -> obj2.method2(payload,header))
            .channel("nullChannel")
            .get();
}


@Bean
public IntegrationFlow bean22() {
    return IntegrationFlows
            .from("subscribableChannel")
            .handle(MyMessage.class, (payload, header) -> obj3.method3(payload))
            .channel("nullChannel")
            .get();
}

В приведенном выше примере, если я внесу изменения в полезную нагрузку в bean-компоненте 21, это повлияет на входную полезную нагрузку, передаваемую в bean-компонент 22.

Мое требование состоит в том, чтобы передать одинаковую полезную нагрузку bean21 и bean 22 и выполнить их параллельно? Не могли бы вы посоветовать, как этого добиться?

1 ответ

Правильно. Spring Integration - это просто Java, и в копировании нет никакой магии payload между разными сообщениями. Это действительно просто один и тот же объект в памяти. Теперь представьте, что у вас есть чистая Java и вы хотите вызвать два разных метода с одинаковым Foo объект. И затем вы модифицируете этот объект одним методом. Что происходит в другом? Правильно, он увидит изменения на объекте.

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

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

Смотрите больше информации в этом JIRA: https://jira.spring.io/browse/INT-2979

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