Skip to content

Commit 6c15e09

Browse files
committed
Order ControllerAdvice beans in controller support
Prior to this commit, the `AnnotatedControllerExceptionResolver` would scan the application context for `@ControllerAdvice` beans and cache the results in an unordered Map. It's later iterating over the entries to resolve an exception handler at runtime. This commit ensures that such entries are now stored in an ordered map, using the `OrderComparator.INSTANCE` comparator. `ControllerAdvice` beans will be iterated over the order specified by the `Ordered` contract or the `@Order` annotation. Fixes gh-830
1 parent 06e485b commit 6c15e09

File tree

2 files changed

+32
-1
lines changed

2 files changed

+32
-1
lines changed

spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/AnnotatedControllerExceptionResolver.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.util.HashMap;
2424
import java.util.List;
2525
import java.util.Map;
26+
import java.util.TreeMap;
2627
import java.util.concurrent.ConcurrentHashMap;
2728

2829
import graphql.GraphQLError;
@@ -36,6 +37,7 @@
3637
import org.springframework.core.KotlinDetector;
3738
import org.springframework.core.MethodIntrospector;
3839
import org.springframework.core.MethodParameter;
40+
import org.springframework.core.OrderComparator;
3941
import org.springframework.core.annotation.AnnotatedElementUtils;
4042
import org.springframework.graphql.data.method.HandlerMethod;
4143
import org.springframework.graphql.data.method.HandlerMethodArgumentResolverComposite;
@@ -80,7 +82,7 @@ final class AnnotatedControllerExceptionResolver {
8082

8183
private final Map<Class<?>, MethodResolver> controllerCache = new ConcurrentHashMap<>(64);
8284

83-
private final Map<ControllerAdviceBean, MethodResolver> controllerAdviceCache = new ConcurrentHashMap<>(64);
85+
private final Map<ControllerAdviceBean, MethodResolver> controllerAdviceCache = new TreeMap<>(OrderComparator.INSTANCE);
8486

8587

8688
AnnotatedControllerExceptionResolver(HandlerMethodArgumentResolverComposite resolvers) {

spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/AnnotatedControllerExceptionResolverTests.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
import org.springframework.context.ApplicationContext;
3232
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
3333
import org.springframework.context.support.StaticApplicationContext;
34+
import org.springframework.core.Ordered;
35+
import org.springframework.core.annotation.Order;
3436
import org.springframework.graphql.data.method.HandlerMethodArgumentResolverComposite;
3537
import org.springframework.graphql.data.method.annotation.GraphQlExceptionHandler;
3638
import org.springframework.lang.Nullable;
@@ -121,6 +123,20 @@ void resolveWithControllerAdvice() {
121123
assertThat(actual.get(0).getMessage()).isEqualTo("handle: Bad input");
122124
}
123125

126+
@Test
127+
void resolveWithOrderedControllerAdvice() {
128+
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
129+
context.register(TestControllerAdvice.class);
130+
context.register(OrderedTestControllerAdvice.class);
131+
context.refresh();
132+
133+
Exception ex = new IllegalArgumentException("Bad input");
134+
List<GraphQLError> actual = exceptionResolver(context).resolveException(ex, this.environment, null).block();
135+
136+
assertThat(actual).hasSize(1);
137+
assertThat(actual.get(0).getMessage()).isEqualTo("ordered handle: Bad input");
138+
}
139+
124140
@Test
125141
void invalidReturnType() {
126142
assertThatIllegalStateException().isThrownBy(() ->
@@ -235,6 +251,19 @@ GraphQLError handle(IllegalArgumentException ex) {
235251
}
236252

237253

254+
@SuppressWarnings("unused")
255+
@ControllerAdvice
256+
@Order(Ordered.HIGHEST_PRECEDENCE)
257+
private static class OrderedTestControllerAdvice {
258+
259+
@GraphQlExceptionHandler
260+
GraphQLError handle(IllegalArgumentException ex) {
261+
return GraphQLError.newError().message("ordered handle: " + ex.getMessage()).build();
262+
}
263+
264+
}
265+
266+
238267
private static class InvalidReturnTypeController {
239268

240269
@GraphQlExceptionHandler

0 commit comments

Comments
 (0)