From f96808edfa8ac574429dcbef9cacddcbdd15f9e2 Mon Sep 17 00:00:00 2001 From: Yanming Zhou Date: Fri, 3 Jul 2026 09:02:27 +0800 Subject: [PATCH 1/2] Apply GraphQL customizers in order See gh-50908 Signed-off-by: Yanming Zhou --- .../autoconfigure/servlet/GraphQlWebMvcAutoConfiguration.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/module/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/servlet/GraphQlWebMvcAutoConfiguration.java b/module/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/servlet/GraphQlWebMvcAutoConfiguration.java index e759dd505d75..3df7ccbd5c2d 100644 --- a/module/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/servlet/GraphQlWebMvcAutoConfiguration.java +++ b/module/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/servlet/GraphQlWebMvcAutoConfiguration.java @@ -81,6 +81,7 @@ * Spring MVC. * * @author Brian Clozel + * @author Yanming Zhou * @since 4.0.0 */ @AutoConfiguration(after = GraphQlAutoConfiguration.class) @@ -203,7 +204,7 @@ GraphQlWebSocketHandler graphQlWebSocketHandler(WebGraphQlHandler webGraphQlHand private HttpMessageConverter getJsonConverter( ObjectProvider customizers) { ServerBuilder serverBuilder = HttpMessageConverters.forServer().registerDefaults(); - customizers.forEach((customizer) -> customizer.customize(serverBuilder)); + customizers.orderedStream().forEach((customizer) -> customizer.customize(serverBuilder)); for (HttpMessageConverter converter : serverBuilder.build()) { if (canReadJsonMap(converter)) { return asObjectHttpMessageConverter(converter); From a57da0c57a01cececaf3315b89efa22f3c15d6d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Nicoll?= Date: Fri, 3 Jul 2026 12:32:28 +0200 Subject: [PATCH 2/2] Polish "Apply GraphQL customizers in order" See gh-50908 --- .../GraphQlWebMvcAutoConfiguration.java | 1 - .../GraphQlWebMvcAutoConfigurationTests.java | 38 +++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/module/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/servlet/GraphQlWebMvcAutoConfiguration.java b/module/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/servlet/GraphQlWebMvcAutoConfiguration.java index 3df7ccbd5c2d..a8fad3d1e509 100644 --- a/module/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/servlet/GraphQlWebMvcAutoConfiguration.java +++ b/module/spring-boot-graphql/src/main/java/org/springframework/boot/graphql/autoconfigure/servlet/GraphQlWebMvcAutoConfiguration.java @@ -81,7 +81,6 @@ * Spring MVC. * * @author Brian Clozel - * @author Yanming Zhou * @since 4.0.0 */ @AutoConfiguration(after = GraphQlAutoConfiguration.class) diff --git a/module/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/servlet/GraphQlWebMvcAutoConfigurationTests.java b/module/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/servlet/GraphQlWebMvcAutoConfigurationTests.java index cf042134ca3d..37e32547b12d 100644 --- a/module/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/servlet/GraphQlWebMvcAutoConfigurationTests.java +++ b/module/spring-boot-graphql/src/test/java/org/springframework/boot/graphql/autoconfigure/servlet/GraphQlWebMvcAutoConfigurationTests.java @@ -24,6 +24,7 @@ import org.assertj.core.api.InstanceOfAssertFactories; import org.assertj.core.api.ThrowingConsumer; import org.junit.jupiter.api.Test; +import org.mockito.InOrder; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; @@ -31,6 +32,7 @@ import org.springframework.boot.graphql.autoconfigure.GraphQlAutoConfiguration; import org.springframework.boot.graphql.autoconfigure.GraphQlTestDataFetchers; import org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration; +import org.springframework.boot.http.converter.autoconfigure.ServerHttpMessageConvertersCustomizer; import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.boot.testsupport.classpath.resources.WithResource; @@ -56,6 +58,9 @@ import org.springframework.web.socket.server.support.WebSocketHandlerMapping; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.mock; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; /** @@ -240,6 +245,22 @@ void shouldConfigureWebSocketBeans() { }); } + @Test + void shouldApplyJsonCustomizersInOrderB() { + this.contextRunner.withPropertyValues("spring.graphql.websocket.path=/ws") + .withUserConfiguration(CustomJsonConverterConfiguration.class) + .run((context) -> { + assertThat(context).hasSingleBean(GraphQlWebSocketHandler.class); + ServerHttpMessageConvertersCustomizer before = context.getBean("before", + ServerHttpMessageConvertersCustomizer.class); + ServerHttpMessageConvertersCustomizer after = context.getBean("after", + ServerHttpMessageConvertersCustomizer.class); + InOrder ordered = inOrder(before, after); + ordered.verify(before).customize(any()); + ordered.verify(after).customize(any()); + }); + } + @Test void shouldConfigureWebSocketProperties() { this.contextRunner @@ -314,6 +335,23 @@ WebGraphQlInterceptor customWebGraphQlInterceptor() { } + @Configuration(proxyBeanMethods = false) + static class CustomJsonConverterConfiguration { + + @Bean + @Order(1) + ServerHttpMessageConvertersCustomizer after() { + return mock(); + } + + @Bean + @Order(-1) + ServerHttpMessageConvertersCustomizer before() { + return mock(); + } + + } + @Configuration static class CustomRouterFunctions {