From bfcc1a1f6ae58d3a62765ddd21f6bd5b5182463d Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 6 Jun 2018 21:25:53 +0200 Subject: [PATCH] ReflectivePropertyAccessor caches sorted methods per class Issue: SPR-16882 --- .../spel/support/ReflectivePropertyAccessor.java | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java b/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java index c7d76480ef..b49cf9e30b 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java @@ -81,6 +81,8 @@ public class ReflectivePropertyAccessor implements PropertyAccessor { private final Map typeDescriptorCache = new ConcurrentHashMap<>(64); + private final Map, Method[]> sortedMethodsCache = new ConcurrentHashMap<>(64); + @Nullable private volatile InvokerPair lastReadInvokerPair; @@ -403,7 +405,7 @@ public class ReflectivePropertyAccessor implements PropertyAccessor { private Method findMethodForProperty(String[] methodSuffixes, String prefix, Class clazz, boolean mustBeStatic, int numberOfParams, Set> requiredReturnTypes) { - Method[] methods = getSortedClassMethods(clazz); + Method[] methods = getSortedMethods(clazz); for (String methodSuffix : methodSuffixes) { for (Method method : methods) { if (isCandidateForProperty(method, clazz) && method.getName().equals(prefix + methodSuffix) && @@ -431,11 +433,15 @@ public class ReflectivePropertyAccessor implements PropertyAccessor { } /** - * Return class methods ordered with non bridge methods appearing higher. + * Return class methods ordered with non-bridge methods appearing higher. */ - private Method[] getSortedClassMethods(Class clazz) { - Method[] methods = clazz.getMethods(); - Arrays.sort(methods, (o1, o2) -> (o1.isBridge() == o2.isBridge() ? 0 : (o1.isBridge() ? 1 : -1))); + private Method[] getSortedMethods(Class clazz) { + Method[] methods = this.sortedMethodsCache.get(clazz); + if (methods == null) { + methods = clazz.getMethods(); + Arrays.sort(methods, (o1, o2) -> (o1.isBridge() == o2.isBridge() ? 0 : (o1.isBridge() ? 1 : -1))); + this.sortedMethodsCache.put(clazz, methods); + } return methods; }