11/* 
2-  * Copyright 2002-2011  the original author or authors. 
2+  * Copyright 2002-2012  the original author or authors. 
33 * 
44 * Licensed under the Apache License, Version 2.0 (the "License"); 
55 * you may not use this file except in compliance with the License. 
2626import  java .lang .reflect .TypeVariable ;
2727import  java .util .HashMap ;
2828import  java .util .Map ;
29+ import  java .util .concurrent .ConcurrentHashMap ;
30+ import  java .util .concurrent .ConcurrentMap ;
2931
3032import  org .springframework .util .Assert ;
3133
3739 * @author Juergen Hoeller 
3840 * @author Rob Harrop 
3941 * @author Andy Clement 
42+  * @author Nikita Tovstoles 
43+  * @author Chris Beams 
4044 * @since 2.0 
4145 * @see GenericCollectionTypeResolver 
4246 */ 
4347public  class  MethodParameter  {
4448
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+ 
4557	private  final  Method  method ;
4658
4759	private  final  Constructor  constructor ;
@@ -280,7 +292,7 @@ public <T extends Annotation> T getMethodAnnotation(Class<T> annotationType) {
280292	public  Annotation [] getParameterAnnotations () {
281293		if  (this .parameterAnnotations  == null ) {
282294			Annotation [][] annotationArray  = (this .method  != null  ?
283- 					this .method . getParameterAnnotations ( ) : this .constructor .getParameterAnnotations ());
295+ 					getMethodParameterAnnotations ( this .method ) : this .constructor .getParameterAnnotations ());
284296			if  (this .parameterIndex  >= 0  && this .parameterIndex  < annotationArray .length ) {
285297				this .parameterAnnotations  = annotationArray [this .parameterIndex ];
286298			}
@@ -439,6 +451,41 @@ else if (methodOrConstructor instanceof Constructor) {
439451		}
440452	}
441453
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+ 
442489	@ Override 
443490	public  boolean  equals (Object  obj ) {
444491		if  (this  == obj ) {
@@ -460,7 +507,6 @@ else if (this.getMember().equals(other.getMember())) {
460507		return  false ;
461508	}
462509
463- 
464510	@ Override 
465511	public  int  hashCode () {
466512		int  result  = this .hash ;
0 commit comments