Cache computed values in SynthesizedAnnotationInvocationHandler

Issue: SPR-11512
This commit is contained in:
Sam Brannen
2015-05-24 15:56:56 +02:00
parent 8ecae8697a
commit b6f2d95c3e

View File

@@ -23,6 +23,7 @@ import java.lang.reflect.Method;
import java.util.Arrays; import java.util.Arrays;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
@@ -57,6 +58,8 @@ class SynthesizedAnnotationInvocationHandler implements InvocationHandler {
private final Map<String, String> aliasMap; private final Map<String, String> aliasMap;
private final Map<String, Object> computedValueCache;
/** /**
* Construct a new {@code SynthesizedAnnotationInvocationHandler}. * Construct a new {@code SynthesizedAnnotationInvocationHandler}.
@@ -73,6 +76,7 @@ class SynthesizedAnnotationInvocationHandler implements InvocationHandler {
this.annotation = annotation; this.annotation = annotation;
this.annotationType = annotation.annotationType(); this.annotationType = annotation.annotationType();
this.aliasMap = aliasMap; this.aliasMap = aliasMap;
this.computedValueCache = new ConcurrentHashMap<String, Object>(aliasMap.size());
} }
@Override @Override
@@ -94,13 +98,19 @@ class SynthesizedAnnotationInvocationHandler implements InvocationHandler {
boolean aliasPresent = (aliasedAttributeName != null); boolean aliasPresent = (aliasedAttributeName != null);
makeAccessible(method); makeAccessible(method);
Object value = invokeMethod(method, this.annotation, args);
// No custom processing necessary? // No custom processing necessary?
if (!aliasPresent && !nestedAnnotation) { if (!aliasPresent && !nestedAnnotation) {
return value; return invokeMethod(method, this.annotation, args);
} }
Object cachedValue = this.computedValueCache.get(methodName);
if (cachedValue != null) {
return cachedValue;
}
Object value = invokeMethod(method, this.annotation, args);
if (aliasPresent) { if (aliasPresent) {
Method aliasedMethod = null; Method aliasedMethod = null;
try { try {
@@ -147,6 +157,8 @@ class SynthesizedAnnotationInvocationHandler implements InvocationHandler {
} }
} }
this.computedValueCache.put(methodName, value);
return value; return value;
} }