Commit a0f29edd authored by Andy Wilkinson's avatar Andy Wilkinson

Always initialize stompWebSocketHandlerMapping eagerly

Previously, when lazy initialization was enabled, STOMP-based WebSocket
messaging would not work as the stompWebSocketHandlerMapping bean was
not initialized and CONNECT requests would go unanswered.

This commit adds a LazyInitializationExcludeFilter that causes the
stompWebSocketHandlerMapping bean to always be initialized eagerly.
This triggers initialization of the WebSocket transport allowing
requests to be received and processed.

Fixes gh-19611
parent 3889e633
/* /*
* Copyright 2012-2019 the original author or authors. * Copyright 2012-2020 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -20,6 +20,7 @@ import java.util.List; ...@@ -20,6 +20,7 @@ import java.util.List;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.boot.LazyInitializationExcludeFilter;
import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
...@@ -27,6 +28,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; ...@@ -27,6 +28,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.converter.ByteArrayMessageConverter; import org.springframework.messaging.converter.ByteArrayMessageConverter;
import org.springframework.messaging.converter.DefaultContentTypeResolver; import org.springframework.messaging.converter.DefaultContentTypeResolver;
...@@ -74,6 +76,11 @@ public class WebSocketMessagingAutoConfiguration { ...@@ -74,6 +76,11 @@ public class WebSocketMessagingAutoConfiguration {
return false; return false;
} }
@Bean
static LazyInitializationExcludeFilter eagerStompWebSocketHandlerMapping() {
return (name, definition, type) -> name.equals("stompWebSocketHandlerMapping");
}
} }
} }
/* /*
* Copyright 2012-2019 the original author or authors. * Copyright 2012-2020 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -31,6 +31,7 @@ import org.junit.jupiter.api.AfterEach; ...@@ -31,6 +31,7 @@ import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.boot.LazyInitializationBeanFactoryPostProcessor;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration;
...@@ -108,6 +109,13 @@ class WebSocketMessagingAutoConfigurationTests { ...@@ -108,6 +109,13 @@ class WebSocketMessagingAutoConfigurationTests {
assertThat(new String((byte[]) result)).isEqualTo("string data"); assertThat(new String((byte[]) result)).isEqualTo("string data");
} }
@Test
void whenLazyInitializationIsEnabledThenBasicMessagingWorks() throws Throwable {
this.context.register(LazyInitializationBeanFactoryPostProcessor.class);
Object result = performStompSubscription("/app/string");
assertThat(new String((byte[]) result)).isEqualTo("string data");
}
@Test @Test
void customizedConverterTypesMatchDefaultConverterTypes() { void customizedConverterTypesMatchDefaultConverterTypes() {
List<MessageConverter> customizedConverters = getCustomizedConverters(); List<MessageConverter> customizedConverters = getCustomizedConverters();
...@@ -190,7 +198,7 @@ class WebSocketMessagingAutoConfigurationTests { ...@@ -190,7 +198,7 @@ class WebSocketMessagingAutoConfigurationTests {
stompClient.connect("ws://localhost:{port}/messaging", handler, stompClient.connect("ws://localhost:{port}/messaging", handler,
this.context.getEnvironment().getProperty("local.server.port")); this.context.getEnvironment().getProperty("local.server.port"));
if (!latch.await(30000, TimeUnit.SECONDS)) { if (!latch.await(30, TimeUnit.SECONDS)) {
if (failure.get() != null) { if (failure.get() != null) {
throw failure.get(); throw failure.get();
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment