如何在 java dsl 中窃听消息通道?

How to wire tap a message channel in java dsl?

我正在尝试 Java dsl spring 集成。我正在尝试窃听一个频道。但是出现错误,

@ContextConfiguration
@EnableIntegration
@IntegrationComponentScan
public class DemoApplication {

  public static void main(String[] args) {

    ApplicationContext ctx = new AnnotationConfigApplicationContext(DemoApplication.class);
    CustomGtwy service = ctx.getBean(CustomGtwy.class);
    service.pushMessage("Manoj");

  }

  @Bean
  public MessageChannel loggerChannel(){
      return MessageChannels.direct().get();
  }

  @Bean
  public MessageChannel pushAssetIdChannel() {
       return MessageChannels.direct()
                  .interceptor(new WireTap(loggerChannel()))
                  .get();
  }

  @Bean
  public IntegrationFlow pushAssetIdFlow() {
      return IntegrationFlows.from("pushAssetIdChannel")
          .handle(new GenericHandler() {
            @Override
            public String handle(Object arg0, Map arg1) {
              // TODO Auto-generated method stub
              return "Success";
            }})
          .get();
  }

  @MessagingGateway
  public interface CustomGtwy{
      @Gateway(requestChannel="pushAssetIdChannel")
    String pushMessage(String s);
  }

  @Bean
  public IntegrationFlow logger(){
      return IntegrationFlows.from("loggerChannel").handle(new GenericHandler() {
        @Override
        public String handle(Object arg0, Map arg1) {
          // TODO Auto-generated method stub
          return "Success";
        }}).channel("nullChannel").get();
  }
}

在上面的代码中,如果我尝试将消息放入 pushAssetIdChannel,我会得到 Dispatcher has no subscribers for channel 'unknown.channel.name'

如果拦截器不存在,它正在工作。

不确定你的案例是怎么回事,但最新的 1.0.2 版本对我有用:

@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@DirtiesContext
public class SO31348246Tests {

    @Autowired
    private MessageChannel pushAssetIdChannel;

    @Test
    public void testIt() {
        this.pushAssetIdChannel.send(new GenericMessage<>("foo"));
    }

    @Configuration
    @EnableIntegration
    public static class ContextConfiguration {

        @Bean
        public MessageChannel loggerChannel() {
            return MessageChannels.direct().get();
        }

        @Bean
        public MessageChannel pushAssetIdChannel() {
            return MessageChannels.direct()
                    .interceptor(new WireTap(loggerChannel()))
                    .get();
        }

        @Bean
        public IntegrationFlow pushAssetIdFlow() {
            return IntegrationFlows.from("pushAssetIdChannel")
                    .handle(System.out::println)
                    .get();
        }

        @Bean
        public IntegrationFlow logger() {
            return IntegrationFlows.from("loggerChannel")
                    .handle((p, h) -> {
                        System.out.println(p);
                        return p;
                    })
                    .channel("nullChannel")
                    .get();
        }

    }

}

我在日志中看到了两个 SOUT

更新

在将 @ContextConfiguration 修改为正常的 @Configuration 注释后,您的 class 对我有用 :-)。

如果没有最后一个,框架会将您的 DemoApplication 视为 lite 配置,只是因为您有 @Bean 方法,但它不会这样做就像 full 一样,并且不代理它以允许使用 bean method reference 就像在 WireTap 构造函数中使用 loggerChannel() 一样。 因此,使用 lite 我们只是调用该方法并获得一个新的 MessageChannel 对象,但它不是应用程序上下文中的 bean。这就是为什么您最终得到 Dispatcher has no subscribers 的原因。