Spring 发布订阅频道接缝的集成广播在窃听时不起作用
Spring Integration Broadcasts of publish-subscribe-channel seams not to work when wiretapping
我在 int:publish-subscribe-channel
上收到消息,但窃听此频道时只会呼叫其中一个订阅者(就像使用直接频道一样)。当我注释掉窃听时,它按预期工作。我正在使用 Spring Boot 2.0.0.RC1
。也可以使用 Spring Boot 1.5.10.RELEASE
.
进行复制
以下配置按预期工作:
起始码:
ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
PublishSubscribeChannel subscribeChannel = context.getBean("subscriber.channel", PublishSubscribeChannel.class);
subscribeChannel.send(MessageBuilder.withPayload("Test-String").build());
context.close();
配置:
<int:publish-subscribe-channel id="subscriber.channel" />
<int:logging-channel-adapter channel="subscriber.channel" level="WARN" />
<int:logging-channel-adapter channel="subscriber.channel" level="ERROR" />
输出:
2018-02-07 16:08:51.308 WARN 11944 --- [ main] o.s.integration.handler.LoggingHandler : Test-String
2018-02-07 16:08:51.315 ERROR 11944 --- [ main] o.s.integration.handler.LoggingHandler : Test-String
当使用通道拦截器时,通道不是发布订阅者通道而是直接通道:
起始码:
ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
PublishSubscribeChannel subscribeChannel = context.getBean("subscriber.channel", PublishSubscribeChannel.class);
subscribeChannel.send(MessageBuilder.withPayload("Test-String").build());
context.close();
配置
<int:publish-subscribe-channel id="subscriber.channel" />
<int:logging-channel-adapter channel="subscriber.channel" level="WARN" />
<int:logging-channel-adapter channel="subscriber.channel" level="ERROR" />
<int:channel id="subscriber.channel">
<int:interceptors>
<int:wire-tap channel="incomeLogger"/>
</int:interceptors>
</int:channel>
<int:logging-channel-adapter id="incomeLogger" level="INFO" />
堆栈跟踪:
Exception in thread "main" 2018-02-07 16:14:42.824 INFO 11928 --- [ Thread-3] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@667a738: startup date [Wed Feb 07 16:14:41 CET 2018]; root of context hierarchy
org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'subscriber.channel' is expected to be of type 'org.springframework.integration.channel.PublishSubscribeChannel' but was actually of type 'org.springframework.integration.channel.DirectChannel'
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:384)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:205)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1091)
at com.example.demo.DemoApplication.main(DemoApplication.java:17)
当我将启动代码更改为:
ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
MessageChannel subscribeChannel = context.getBean("subscriber.channel", MessageChannel.class);
subscribeChannel.send(MessageBuilder.withPayload("Test-String").build());
context.close();
然后一个"Subscriber"会被调用,通道被拦截器跟踪:
2018-02-07 16:17:11.415 INFO 10040 --- [ main] o.s.integration.handler.LoggingHandler : Test-String
2018-02-07 16:17:11.416 WARN 10040 --- [ main] o.s.integration.handler.LoggingHandler : Test-String
更新:
同样有效的是以下配置
<int:publish-subscribe-channel id="subscriber.channel">
<int:interceptors>
<int:wire-tap channel="incomeLogger"/>
</int:interceptors>
</int:publish-subscribe-channel>
<int:logging-channel-adapter id="incomeLogger" level="INFO" />
<int:logging-channel-adapter channel="subscriber.channel" level="WARN" />
<int:logging-channel-adapter channel="subscriber.channel" level="ERROR" />
输出:
2018-02-07 17:08:56.923 INFO 11300 --- [ main] o.s.integration.handler.LoggingHandler : Test-String
2018-02-07 17:08:56.923 WARN 11300 --- [ main] o.s.integration.handler.LoggingHandler : Test-String
2018-02-07 17:08:56.923 ERROR 11300 --- [ main] o.s.integration.handler.LoggingHandler : Test-String
这是预期的还是错误?或者我错过了什么?提前致谢。
看看你有什么:
<int:publish-subscribe-channel id="subscriber.channel" />
<int:channel id="subscriber.channel">
<int:interceptors>
<int:wire-tap channel="incomeLogger"/>
</int:interceptors>
</int:channel>
实际上你声明了两个bean,但是它们都具有相同的id
。因此,只有定义顺序中的第二个获胜。但由于它是一个简单的 channel
,您肯定会在运行时以 DirectChannel
结束,从而消除了出现该 publish-subscribe-channel
结果的任何可能性。
你应该明白,XML配置是经过解析的,最终的真实对象模型可能会有所不同。
因此,您错误地使用相同的 id
.
覆盖了目标 bean
您的 <int:interceptors>
<int:publish-subscribe-channel id="subscriber.channel">
的最新代码是正确的。而且我相信最新的日志正是您希望看到的。
我在 int:publish-subscribe-channel
上收到消息,但窃听此频道时只会呼叫其中一个订阅者(就像使用直接频道一样)。当我注释掉窃听时,它按预期工作。我正在使用 Spring Boot 2.0.0.RC1
。也可以使用 Spring Boot 1.5.10.RELEASE
.
以下配置按预期工作:
起始码:
ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
PublishSubscribeChannel subscribeChannel = context.getBean("subscriber.channel", PublishSubscribeChannel.class);
subscribeChannel.send(MessageBuilder.withPayload("Test-String").build());
context.close();
配置:
<int:publish-subscribe-channel id="subscriber.channel" />
<int:logging-channel-adapter channel="subscriber.channel" level="WARN" />
<int:logging-channel-adapter channel="subscriber.channel" level="ERROR" />
输出:
2018-02-07 16:08:51.308 WARN 11944 --- [ main] o.s.integration.handler.LoggingHandler : Test-String
2018-02-07 16:08:51.315 ERROR 11944 --- [ main] o.s.integration.handler.LoggingHandler : Test-String
当使用通道拦截器时,通道不是发布订阅者通道而是直接通道:
起始码:
ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
PublishSubscribeChannel subscribeChannel = context.getBean("subscriber.channel", PublishSubscribeChannel.class);
subscribeChannel.send(MessageBuilder.withPayload("Test-String").build());
context.close();
配置
<int:publish-subscribe-channel id="subscriber.channel" />
<int:logging-channel-adapter channel="subscriber.channel" level="WARN" />
<int:logging-channel-adapter channel="subscriber.channel" level="ERROR" />
<int:channel id="subscriber.channel">
<int:interceptors>
<int:wire-tap channel="incomeLogger"/>
</int:interceptors>
</int:channel>
<int:logging-channel-adapter id="incomeLogger" level="INFO" />
堆栈跟踪:
Exception in thread "main" 2018-02-07 16:14:42.824 INFO 11928 --- [ Thread-3] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@667a738: startup date [Wed Feb 07 16:14:41 CET 2018]; root of context hierarchy
org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'subscriber.channel' is expected to be of type 'org.springframework.integration.channel.PublishSubscribeChannel' but was actually of type 'org.springframework.integration.channel.DirectChannel'
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:384)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:205)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1091)
at com.example.demo.DemoApplication.main(DemoApplication.java:17)
当我将启动代码更改为:
ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
MessageChannel subscribeChannel = context.getBean("subscriber.channel", MessageChannel.class);
subscribeChannel.send(MessageBuilder.withPayload("Test-String").build());
context.close();
然后一个"Subscriber"会被调用,通道被拦截器跟踪:
2018-02-07 16:17:11.415 INFO 10040 --- [ main] o.s.integration.handler.LoggingHandler : Test-String
2018-02-07 16:17:11.416 WARN 10040 --- [ main] o.s.integration.handler.LoggingHandler : Test-String
更新:
同样有效的是以下配置
<int:publish-subscribe-channel id="subscriber.channel">
<int:interceptors>
<int:wire-tap channel="incomeLogger"/>
</int:interceptors>
</int:publish-subscribe-channel>
<int:logging-channel-adapter id="incomeLogger" level="INFO" />
<int:logging-channel-adapter channel="subscriber.channel" level="WARN" />
<int:logging-channel-adapter channel="subscriber.channel" level="ERROR" />
输出:
2018-02-07 17:08:56.923 INFO 11300 --- [ main] o.s.integration.handler.LoggingHandler : Test-String
2018-02-07 17:08:56.923 WARN 11300 --- [ main] o.s.integration.handler.LoggingHandler : Test-String
2018-02-07 17:08:56.923 ERROR 11300 --- [ main] o.s.integration.handler.LoggingHandler : Test-String
这是预期的还是错误?或者我错过了什么?提前致谢。
看看你有什么:
<int:publish-subscribe-channel id="subscriber.channel" />
<int:channel id="subscriber.channel">
<int:interceptors>
<int:wire-tap channel="incomeLogger"/>
</int:interceptors>
</int:channel>
实际上你声明了两个bean,但是它们都具有相同的id
。因此,只有定义顺序中的第二个获胜。但由于它是一个简单的 channel
,您肯定会在运行时以 DirectChannel
结束,从而消除了出现该 publish-subscribe-channel
结果的任何可能性。
你应该明白,XML配置是经过解析的,最终的真实对象模型可能会有所不同。
因此,您错误地使用相同的 id
.
您的 <int:interceptors>
<int:publish-subscribe-channel id="subscriber.channel">
的最新代码是正确的。而且我相信最新的日志正是您希望看到的。