Мои приложения 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);
, приложение запускается нормально, и мои WebSockets работают прекрасно.
Кажется, что при получении bean-компонентов через applicationContext.getBean(beanName)
, метод @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
устарела, но я не нашел никаких указанийо том, что использовать вместо.