23
23
import java .util .Arrays ;
24
24
import java .util .Iterator ;
25
25
import java .util .Map ;
26
+ import java .util .concurrent .ConcurrentHashMap ;
26
27
27
28
import org .springframework .util .ObjectUtils ;
28
29
import org .springframework .util .StringUtils ;
@@ -57,6 +58,8 @@ class SynthesizedAnnotationInvocationHandler implements InvocationHandler {
57
58
58
59
private final Map <String , String > aliasMap ;
59
60
61
+ private final Map <String , Object > computedValueCache ;
62
+
60
63
61
64
/**
62
65
* Construct a new {@code SynthesizedAnnotationInvocationHandler}.
@@ -73,6 +76,7 @@ class SynthesizedAnnotationInvocationHandler implements InvocationHandler {
73
76
this .annotation = annotation ;
74
77
this .annotationType = annotation .annotationType ();
75
78
this .aliasMap = aliasMap ;
79
+ this .computedValueCache = new ConcurrentHashMap <String , Object >(aliasMap .size ());
76
80
}
77
81
78
82
@ Override
@@ -94,13 +98,19 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl
94
98
boolean aliasPresent = (aliasedAttributeName != null );
95
99
96
100
makeAccessible (method );
97
- Object value = invokeMethod (method , this .annotation , args );
98
101
99
102
// No custom processing necessary?
100
103
if (!aliasPresent && !nestedAnnotation ) {
101
- return value ;
104
+ return invokeMethod (method , this .annotation , args );
105
+ }
106
+
107
+ Object cachedValue = this .computedValueCache .get (methodName );
108
+ if (cachedValue != null ) {
109
+ return cachedValue ;
102
110
}
103
111
112
+ Object value = invokeMethod (method , this .annotation , args );
113
+
104
114
if (aliasPresent ) {
105
115
Method aliasedMethod = null ;
106
116
try {
@@ -147,6 +157,8 @@ else if (value instanceof Annotation[]) {
147
157
}
148
158
}
149
159
160
+ this .computedValueCache .put (methodName , value );
161
+
150
162
return value ;
151
163
}
152
164
0 commit comments