我的Spring Boot WebSocket应用程序抛出:
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:185) ~[spring-context-5.1.4.RELEASE.jar:5.1.4.RELEASE]
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:174) ~[spring-context-5.1.4.RELEASE.jar:5.1.4.RELEASE]
at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:53) ~[spring-context-5.1.4.RELEASE.jar:5.1.4.RELEASE]
并且我已经隔离出问题来自我的@Postconstruct
方法中的一行代码:
@Component
public class AuthenticationChannelInterceptorAdapter implements ChannelInterceptor {
@Autowired
private ApplicationContext applicationContext;
@PostConstruct
public void initialized() {
for (String beanName : applicationContext.getBeanDefinitionNames()) {
System.out.println(beanName);
// The line below causes the error
Object bean = applicationContext.getBean(beanName);
}
}
@Override
public Message<?> preSend(final Message<?> message, final MessageChannel channel) throws AuthenticationException {
return message;
}
}
当我注释掉Object bean = applicationContext.getBean(beanName);
时,该应用程序可以正常启动,并且我的WebSocket可以正常工作。
似乎通过applicationContext.getBean(beanName)
获取bean时,@PostConstruct
方法执行时间更长,这导致依赖它的代码的其他部分中断。
作为参考,这是我的拦截器的注册方式:
@Configuration
@EnableWebSocketMessageBroker
public class StompWebsocketConfig implements WebSocketMessageBrokerConfigurer {
@Autowired
private AuthenticationChannelInterceptorAdapter authenticationChannelInterceptorAdapter;
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry
.setApplicationDestinationPrefixes("/app")
.enableSimpleBroker("/topic");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws-endpoint").withSockJS();
}
@Override
public void configureClientInboundChannel(final ChannelRegistration registration) {
registration.setInterceptors(authenticationChannelInterceptorAdapter);
}
}
我知道registration.setInterceptors
已过时,但我没有找到任何替代方法的指南。