Skip to content

Commit 4a6e9a5

Browse files
committed
ReflectivePropertyAccessor caches sorted methods per class
Issue: SPR-16882
1 parent 357ca21 commit 4a6e9a5

File tree

1 file changed

+19
-11
lines changed

1 file changed

+19
-11
lines changed

spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,10 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
8383
private final Map<PropertyCacheKey, TypeDescriptor> typeDescriptorCache =
8484
new ConcurrentHashMap<PropertyCacheKey, TypeDescriptor>(64);
8585

86-
private InvokerPair lastReadInvokerPair;
86+
private final Map<Class<?>, Method[]> sortedMethodsCache =
87+
new ConcurrentHashMap<Class<?>, Method[]>(64);
88+
89+
private volatile InvokerPair lastReadInvokerPair;
8790

8891

8992
/**
@@ -277,6 +280,7 @@ public void write(EvaluationContext context, Object target, String name, Object
277280
throw new AccessException("Type conversion failure", evaluationException);
278281
}
279282
}
283+
280284
PropertyCacheKey cacheKey = new PropertyCacheKey(type, name, target instanceof Class);
281285
Member cachedMember = this.writerCache.get(cacheKey);
282286

@@ -400,7 +404,7 @@ protected Method findSetterForProperty(String propertyName, Class<?> clazz, bool
400404
private Method findMethodForProperty(String[] methodSuffixes, String prefix, Class<?> clazz,
401405
boolean mustBeStatic, int numberOfParams, Set<Class<?>> requiredReturnTypes) {
402406

403-
Method[] methods = getSortedClassMethods(clazz);
407+
Method[] methods = getSortedMethods(clazz);
404408
for (String methodSuffix : methodSuffixes) {
405409
for (Method method : methods) {
406410
if (isCandidateForProperty(method, clazz) && method.getName().equals(prefix + methodSuffix) &&
@@ -428,16 +432,20 @@ protected boolean isCandidateForProperty(Method method, Class<?> targetClass) {
428432
}
429433

430434
/**
431-
* Return class methods ordered with non bridge methods appearing higher.
435+
* Return class methods ordered with non-bridge methods appearing higher.
432436
*/
433-
private Method[] getSortedClassMethods(Class<?> clazz) {
434-
Method[] methods = clazz.getMethods();
435-
Arrays.sort(methods, new Comparator<Method>() {
436-
@Override
437-
public int compare(Method o1, Method o2) {
438-
return (o1.isBridge() == o2.isBridge()) ? 0 : (o1.isBridge() ? 1 : -1);
439-
}
440-
});
437+
private Method[] getSortedMethods(Class<?> clazz) {
438+
Method[] methods = this.sortedMethodsCache.get(clazz);
439+
if (methods == null) {
440+
methods = clazz.getMethods();
441+
Arrays.sort(methods, new Comparator<Method>() {
442+
@Override
443+
public int compare(Method o1, Method o2) {
444+
return (o1.isBridge() == o2.isBridge()) ? 0 : (o1.isBridge() ? 1 : -1);
445+
}
446+
});
447+
this.sortedMethodsCache.put(clazz, methods);
448+
}
441449
return methods;
442450
}
443451

0 commit comments

Comments
 (0)