spring WebSocket 拦截器和 spring 云流的依赖循环
dependency cycle on spring WebSocket interceptor and spring cloud stream
我正在尝试创建一个 websocket 拦截器,它使用来自 spring 云流的 MessageChannel 发送消息。我正面临依赖周期
┌─────┐
| myChannelInterceptor defined in file [/Users/shahbour/IdeaProjects/proxy/target/classes/com/xxxxx/proxy/broker/MyChannelInterceptor.class]
↑ ↓
| com.xxxx.proxy.service.XxxxxBinding (field private java.util.Map org.springframework.cloud.stream.binding.BindableProxyFactory.bindingTargetFactories)
↑ ↓
| org.springframework.cloud.stream.config.BindingServiceConfiguration (field private java.util.List org.springframework.cloud.stream.config.BindingServiceConfiguration.customMessageConverters)
↑ ↓
| org.springframework.web.socket.config.annotation.DelegatingWebSocketMessageBrokerConfiguration
↑ ↓
| webSocketConfig defined in file [/Users/shahbour/IdeaProjects/proxy/target/classes/com/xxxx/proxy/config/WebSocketConfig.class]
└─────┘
我的问题是我需要将 MessageChannel 注入 websocket 拦截器
如果我使用@Autowire
,我会收到以下错误
org.springframework.context.ApplicationContextException: Failed to start bean 'subProtocolWebSocketHandler'; nested exception is java.lang.IllegalArgumentException: No handlers
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:178) ~[spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:167) ~[spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.context.support.DefaultLifecycleProcessor.access0(DefaultLifecycleProcessor.java:50) ~[spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:348) ~[spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:151) ~[spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:114) ~[spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:879) ~[spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.finishRefresh(EmbeddedWebApplicationContext.java:144) ~[spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:545) ~[spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:737) [spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:370) [spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:314) [spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1162) [spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1151) [spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE]
at com.xxxx.proxy.xxxxxxProxyApplication.main(XxxxxProxyApplication.java:29) [classes/:na]
Caused by: java.lang.IllegalArgumentException: No handlers
at org.springframework.util.Assert.isTrue(Assert.java:92) ~[spring-core-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.web.socket.messaging.SubProtocolWebSocketHandler.start(SubProtocolWebSocketHandler.java:244) ~[spring-websocket-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:175) ~[spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE]
... 15 common frames omitted
好的。谢谢!不,我看到了问题。
看:
- 您的
MyChannelInterceptor
取决于 BinderService
自动创建的频道。
- 那个人试图从应用程序上下文中推断出
MessageConverter
s。
AbstractMessageBrokerConfiguration
提供了一个面对CompositeMessageConverter brokerMessageConverter
- class 由
@EnableWebSocketMessageBroker
实例化
- 反过来,由于
AbstractWebSocketMessageBrokerConfigurer
,它会扫描您的 WebSocketConfig
- 最后一个要注射你的
MyChannelInterceptor
。
不确定如何将其修复为开箱即用的功能,但这里有一些解决方法:
public class MyChannelInterceptor extends ChannelInterceptorAdapter {
@Autowired
private MessageChannel output;
@Configuration
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Bean
public MyChannelInterceptor myChannelInterceptor() {
return new MyChannelInterceptor();
}
...
@Override
public void configureClientInboundChannel(ChannelRegistration registration) {
registration.setInterceptors(myChannelInterceptor());
}
我正在尝试创建一个 websocket 拦截器,它使用来自 spring 云流的 MessageChannel 发送消息。我正面临依赖周期
┌─────┐
| myChannelInterceptor defined in file [/Users/shahbour/IdeaProjects/proxy/target/classes/com/xxxxx/proxy/broker/MyChannelInterceptor.class]
↑ ↓
| com.xxxx.proxy.service.XxxxxBinding (field private java.util.Map org.springframework.cloud.stream.binding.BindableProxyFactory.bindingTargetFactories)
↑ ↓
| org.springframework.cloud.stream.config.BindingServiceConfiguration (field private java.util.List org.springframework.cloud.stream.config.BindingServiceConfiguration.customMessageConverters)
↑ ↓
| org.springframework.web.socket.config.annotation.DelegatingWebSocketMessageBrokerConfiguration
↑ ↓
| webSocketConfig defined in file [/Users/shahbour/IdeaProjects/proxy/target/classes/com/xxxx/proxy/config/WebSocketConfig.class]
└─────┘
我的问题是我需要将 MessageChannel 注入 websocket 拦截器
如果我使用@Autowire
,我会收到以下错误org.springframework.context.ApplicationContextException: Failed to start bean 'subProtocolWebSocketHandler'; nested exception is java.lang.IllegalArgumentException: No handlers
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:178) ~[spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:167) ~[spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.context.support.DefaultLifecycleProcessor.access0(DefaultLifecycleProcessor.java:50) ~[spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:348) ~[spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:151) ~[spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:114) ~[spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:879) ~[spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.finishRefresh(EmbeddedWebApplicationContext.java:144) ~[spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:545) ~[spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:737) [spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:370) [spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:314) [spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1162) [spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1151) [spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE]
at com.xxxx.proxy.xxxxxxProxyApplication.main(XxxxxProxyApplication.java:29) [classes/:na]
Caused by: java.lang.IllegalArgumentException: No handlers
at org.springframework.util.Assert.isTrue(Assert.java:92) ~[spring-core-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.web.socket.messaging.SubProtocolWebSocketHandler.start(SubProtocolWebSocketHandler.java:244) ~[spring-websocket-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:175) ~[spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE]
... 15 common frames omitted
好的。谢谢!不,我看到了问题。
看:
- 您的
MyChannelInterceptor
取决于BinderService
自动创建的频道。 - 那个人试图从应用程序上下文中推断出
MessageConverter
s。 AbstractMessageBrokerConfiguration
提供了一个面对CompositeMessageConverter brokerMessageConverter
- class 由
@EnableWebSocketMessageBroker
实例化
- 反过来,由于
AbstractWebSocketMessageBrokerConfigurer
,它会扫描您的 - 最后一个要注射你的
MyChannelInterceptor
。
WebSocketConfig
不确定如何将其修复为开箱即用的功能,但这里有一些解决方法:
public class MyChannelInterceptor extends ChannelInterceptorAdapter {
@Autowired
private MessageChannel output;
@Configuration
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Bean
public MyChannelInterceptor myChannelInterceptor() {
return new MyChannelInterceptor();
}
...
@Override
public void configureClientInboundChannel(ChannelRegistration registration) {
registration.setInterceptors(myChannelInterceptor());
}