Commit 943a054b authored by Andy Wilkinson's avatar Andy Wilkinson

Remove ineffective, premature optimisation from ErrorPageFilter

ErrorPageFilter contained an optimisation for looking up the path
of an error page by exception type. For cases where there was no
mapping for the type of the exception that was thrown but there
was a mapping for one of its super classes, it was intended to
speed up the lookup. Unfortunately, there was a bug in the
implementation which meant that the optimisation had no effect.

Analysis with JMH reveals that for an Exception with a deep type
hierarchy, such as Spring Framework's UnsatisfiedDependencyException,
and an error page mapping for Exception, searching up the hierarchy
until a mapping is found takes 0.0000001s. With the same mapping,
a lookup for Exception takes 0.00000001s, i.e. it's 10x faster.
The optimisation, when correctly implemented, brings the time for
UnsatisfiedDependencyException down to 0.00000001s and into line
with a lookup for Exception. However, the amount of time involved is
so small compared to the overall time spent processing a request that
the added complexity of the optimisation is not justified.

Closes gh-7010
parent 02e89acd
...@@ -83,8 +83,6 @@ public class ErrorPageFilter implements Filter, ErrorPageRegistry { ...@@ -83,8 +83,6 @@ public class ErrorPageFilter implements Filter, ErrorPageRegistry {
private final Map<Class<?>, String> exceptions = new HashMap<Class<?>, String>(); private final Map<Class<?>, String> exceptions = new HashMap<Class<?>, String>();
private final Map<Class<?>, Class<?>> subtypes = new HashMap<Class<?>, Class<?>>();
private final OncePerRequestFilter delegate = new OncePerRequestFilter() { private final OncePerRequestFilter delegate = new OncePerRequestFilter() {
@Override @Override
...@@ -217,19 +215,12 @@ public class ErrorPageFilter implements Filter, ErrorPageRegistry { ...@@ -217,19 +215,12 @@ public class ErrorPageFilter implements Filter, ErrorPageRegistry {
} }
private String getErrorPath(Class<?> type) { private String getErrorPath(Class<?> type) {
if (this.exceptions.containsKey(type)) { while (type != Object.class) {
return this.exceptions.get(type); String path = this.exceptions.get(type);
} if (path != null) {
if (this.subtypes.containsKey(type)) { return path;
return this.exceptions.get(this.subtypes.get(type));
}
Class<?> subtype = type;
while (subtype != Object.class) {
subtype = subtype.getSuperclass();
if (this.exceptions.containsKey(subtype)) {
this.subtypes.put(subtype, type);
return this.exceptions.get(subtype);
} }
type = type.getSuperclass();
} }
return this.global; return this.global;
} }
......
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