Skip to content

Commit 689b556

Browse files
committed
Cache "no match" result from ExceptionHandler methods
Closes gh-26339
1 parent 234b471 commit 689b556

File tree

2 files changed

+43
-7
lines changed

2 files changed

+43
-7
lines changed

spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/AbstractExceptionHandlerMethodResolver.java

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -38,6 +38,19 @@
3838
*/
3939
public abstract class AbstractExceptionHandlerMethodResolver {
4040

41+
private static final Method NO_MATCHING_EXCEPTION_HANDLER_METHOD;
42+
43+
static {
44+
try {
45+
NO_MATCHING_EXCEPTION_HANDLER_METHOD =
46+
AbstractExceptionHandlerMethodResolver.class.getDeclaredMethod("noMatchingExceptionHandler");
47+
}
48+
catch (NoSuchMethodException ex) {
49+
throw new IllegalStateException("Expected method not found: " + ex);
50+
}
51+
}
52+
53+
4154
private final Map<Class<? extends Throwable>, Method> mappedMethods = new HashMap<>(16);
4255

4356
private final Map<Class<? extends Throwable>, Method> exceptionLookupCache = new ConcurrentReferenceHashMap<>(16);
@@ -110,7 +123,7 @@ public Method resolveMethodByExceptionType(Class<? extends Throwable> exceptionT
110123
method = getMappedMethod(exceptionType);
111124
this.exceptionLookupCache.put(exceptionType, method);
112125
}
113-
return method;
126+
return (method != NO_MATCHING_EXCEPTION_HANDLER_METHOD ? method : null);
114127
}
115128

116129
/**
@@ -129,8 +142,14 @@ private Method getMappedMethod(Class<? extends Throwable> exceptionType) {
129142
return this.mappedMethods.get(matches.get(0));
130143
}
131144
else {
132-
return null;
145+
return NO_MATCHING_EXCEPTION_HANDLER_METHOD;
133146
}
134147
}
135148

149+
/**
150+
* For the NO_MATCHING_EXCEPTION_HANDLER_METHOD constant.
151+
*/
152+
private void noMatchingExceptionHandler() {
153+
}
154+
136155
}

spring-web/src/main/java/org/springframework/web/method/annotation/ExceptionHandlerMethodResolver.java

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -49,6 +49,18 @@ public class ExceptionHandlerMethodResolver {
4949
public static final MethodFilter EXCEPTION_HANDLER_METHODS = method ->
5050
AnnotatedElementUtils.hasAnnotation(method, ExceptionHandler.class);
5151

52+
private static final Method NO_MATCHING_EXCEPTION_HANDLER_METHOD;
53+
54+
static {
55+
try {
56+
NO_MATCHING_EXCEPTION_HANDLER_METHOD =
57+
ExceptionHandlerMethodResolver.class.getDeclaredMethod("noMatchingExceptionHandler");
58+
}
59+
catch (NoSuchMethodException ex) {
60+
throw new IllegalStateException("Expected method not found: " + ex);
61+
}
62+
}
63+
5264

5365
private final Map<Class<? extends Throwable>, Method> mappedMethods = new HashMap<>(16);
5466

@@ -153,13 +165,12 @@ public Method resolveMethodByExceptionType(Class<? extends Throwable> exceptionT
153165
method = getMappedMethod(exceptionType);
154166
this.exceptionLookupCache.put(exceptionType, method);
155167
}
156-
return method;
168+
return (method != NO_MATCHING_EXCEPTION_HANDLER_METHOD ? method : null);
157169
}
158170

159171
/**
160172
* Return the {@link Method} mapped to the given exception type, or {@code null} if none.
161173
*/
162-
@Nullable
163174
private Method getMappedMethod(Class<? extends Throwable> exceptionType) {
164175
List<Class<? extends Throwable>> matches = new ArrayList<>();
165176
for (Class<? extends Throwable> mappedException : this.mappedMethods.keySet()) {
@@ -172,8 +183,14 @@ private Method getMappedMethod(Class<? extends Throwable> exceptionType) {
172183
return this.mappedMethods.get(matches.get(0));
173184
}
174185
else {
175-
return null;
186+
return NO_MATCHING_EXCEPTION_HANDLER_METHOD;
176187
}
177188
}
178189

190+
/**
191+
* For the NO_MATCHING_EXCEPTION_HANDLER_METHOD constant.
192+
*/
193+
private void noMatchingExceptionHandler() {
194+
}
195+
179196
}

0 commit comments

Comments
 (0)