Ченнелинг интеграции Spring с именем компонента и именем метода

У меня есть PublishSubscribeChannel следующим образом:

@Bean(name = {"publishCha.input", "publishCha2.input"}) //2 subscribers
    public MessageChannel publishAction() {
        PublishSubscribeChannel ps = MessageChannels.publishSubscribe().get();
        ps.setMaxSubscribers(8);
        return ps;
    }

У меня также есть каналы подписчиков:

@Bean
    public IntegrationFlow publishCha() {
        return f -> f
                .handle(m -> System.out.println("In publishCha channel..."));
    }


@Bean
    public IntegrationFlow publishCha2() {
        return f -> f
                .handle(m -> System.out.println("In publishCha2 channel..."));
    }

И напоследок еще один подписчик:

@Bean
    public IntegrationFlow anotherChannel() {
        return IntegrationFlows.from("publishAction")
                .handle(m -> System.out.println("ANOTHER CHANNEL IS HERE!"))
                .get();
    }

Проблема в том, что когда я вызываю канал с именем метода «publishAction», как показано ниже, из другого потока, он печатает только «ДРУГОЙ КАНАЛ ЗДЕСЬ» и игнорирует других подписчиков. Однако, если я позвоню с .channel("publishCha.input"), на этот раз он войдет в подписчиков publishCha и publishCha2, но проигнорирует третьего подписчика.

@Bean
    public IntegrationFlow flow() { 
        return f -> f
       .channel("publishAction");
    }

Мой вопрос: почему эти два разных метода ченнелинга дают разные результаты?

.channel("publishAction") // channeling with method name executes third subscriber

.channel("publishCha.input") // channelling with bean name, executes first and second subscribers

Редактировать: narayan-sambireddy спросил, как я могу отправлять сообщения на канал. Я отправляю его через шлюз:

@MessagingGateway
public interface ExampleGateway {

@Gateway(requestChannel = "flow.input")
    void flow(Order orders);
}

В основном:

Order order = new Order();
      order.addItem("PC", "TTEL", 2000, 1)
    ConfigurableApplicationContext ctx = SpringApplication.run(Start.class, args);
    ctx.getBean(ExampleGateway.class).flow(order);

person sarah    schedule 14.05.2018    source источник
comment
Не могли бы вы также опубликовать, как вы отправляете сообщения на эти каналы - хотел проверить, как вы ссылаетесь на эти каналы (beanName или methodName) при отправке сообщений.   -  person narayan-sambireddy    schedule 14.05.2018
comment
@narayan-sambireddy добавил я.   -  person sarah    schedule 14.05.2018


Ответы (1)


Ваша проблема с третьим подписчиком, что вы пропускаете цель name в @Bean:

/**
 * The name of this bean, or if several names, a primary bean name plus aliases.
 * <p>If left unspecified, the name of the bean is the name of the annotated method.
 * If specified, the method name is ignored.
 * <p>The bean name and aliases may also be configured via the {@link #value}
 * attribute if no other attributes are declared.
 * @see #value
 */
@AliasFor("value")
String[] name() default {};

Таким образом, имя метода в качестве имени компонента в этом случае игнорируется, поэтому Spring Integration Java DSL не находит компонент с publishAction и создает его — DirectChannel.

Однако вы можете использовать ссылку на метод:

IntegrationFlows.from(publishAction())

Или, если это другой класс конфигурации, вы можете повторно использовать одно из предопределенных имен.

 IntegrationFlows.from(publishCha.input)

Таким образом, DSL будет повторно использовать существующий bean-компонент и просто добавит еще одного подписчика к этому каналу pub-sub.

person Artem Bilan    schedule 14.05.2018
comment
Спасибо, что потратили время на объяснение. - person sarah; 14.05.2018