1
1
/*
2
- * Copyright 2002-2011 the original author or authors.
2
+ * Copyright 2002-2012 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
26
26
import java .lang .reflect .TypeVariable ;
27
27
import java .util .HashMap ;
28
28
import java .util .Map ;
29
+ import java .util .concurrent .ConcurrentHashMap ;
30
+ import java .util .concurrent .ConcurrentMap ;
29
31
30
32
import org .springframework .util .Assert ;
31
33
37
39
* @author Juergen Hoeller
38
40
* @author Rob Harrop
39
41
* @author Andy Clement
42
+ * @author Nikita Tovstoles
43
+ * @author Chris Beams
40
44
* @since 2.0
41
45
* @see GenericCollectionTypeResolver
42
46
*/
43
47
public class MethodParameter {
44
48
49
+
50
+ private static final Annotation [][] EMPTY_ANNOTATION_MATRIX = new Annotation [0 ][0 ];
51
+
52
+ private static final Annotation [] EMPTY_ANNOTATION_ARRAY = new Annotation [0 ];
53
+
54
+ static final ConcurrentMap <Method , Annotation [][]> methodParamAnnotationsCache =
55
+ new ConcurrentHashMap <Method , Annotation [][]>();
56
+
45
57
private final Method method ;
46
58
47
59
private final Constructor constructor ;
@@ -280,7 +292,7 @@ public <T extends Annotation> T getMethodAnnotation(Class<T> annotationType) {
280
292
public Annotation [] getParameterAnnotations () {
281
293
if (this .parameterAnnotations == null ) {
282
294
Annotation [][] annotationArray = (this .method != null ?
283
- this .method . getParameterAnnotations ( ) : this .constructor .getParameterAnnotations ());
295
+ getMethodParameterAnnotations ( this .method ) : this .constructor .getParameterAnnotations ());
284
296
if (this .parameterIndex >= 0 && this .parameterIndex < annotationArray .length ) {
285
297
this .parameterAnnotations = annotationArray [this .parameterIndex ];
286
298
}
@@ -439,6 +451,41 @@ else if (methodOrConstructor instanceof Constructor) {
439
451
}
440
452
}
441
453
454
+ /**
455
+ * Return the parameter annotations for the given method, retrieving cached values
456
+ * if a lookup has already been performed for this method, otherwise perform a fresh
457
+ * lookup and populate the cache with the result before returning. <strong>For
458
+ * internal use only.</strong>
459
+ * @param method the method to introspect for parameter annotations
460
+ */
461
+ static Annotation [][] getMethodParameterAnnotations (Method method ) {
462
+ Assert .notNull (method );
463
+
464
+ Annotation [][] result = methodParamAnnotationsCache .get (method );
465
+ if (result == null ) {
466
+ result = method .getParameterAnnotations ();
467
+
468
+ if (result .length == 0 ) {
469
+ result = EMPTY_ANNOTATION_MATRIX ;
470
+ }
471
+ else {
472
+ for (int i = 0 ; i < result .length ; i ++) {
473
+ if (result [i ].length == 0 ) {
474
+ result [i ] = EMPTY_ANNOTATION_ARRAY ;
475
+ }
476
+ }
477
+ }
478
+ methodParamAnnotationsCache .put (method , result );
479
+ }
480
+
481
+ //always return deep copy to prevent caller from modifying cache state
482
+ Annotation [][] resultCopy = new Annotation [result .length ][0 ];
483
+ for (int i = 0 ; i < result .length ; i ++) {
484
+ resultCopy [i ] = result [i ].clone ();
485
+ }
486
+ return resultCopy ;
487
+ }
488
+
442
489
@ Override
443
490
public boolean equals (Object obj ) {
444
491
if (this == obj ) {
@@ -460,7 +507,6 @@ else if (this.getMember().equals(other.getMember())) {
460
507
return false ;
461
508
}
462
509
463
-
464
510
@ Override
465
511
public int hashCode () {
466
512
int result = this .hash ;
0 commit comments