@ -31,6 +31,7 @@ import java.util.Arrays;
@@ -31,6 +31,7 @@ import java.util.Arrays;
import java.util.Comparator ;
import java.util.Set ;
import org.springframework.beans.BeanMetadataElement ;
import org.springframework.beans.factory.ObjectFactory ;
import org.springframework.beans.factory.config.TypedStringValue ;
import org.springframework.util.Assert ;
@ -195,8 +196,8 @@ abstract class AutowireUtils {
@@ -195,8 +196,8 @@ abstract class AutowireUtils {
TypeVariable < Method > [ ] declaredTypeVariables = method . getTypeParameters ( ) ;
Type genericReturnType = method . getGenericReturnType ( ) ;
Type [ ] methodArgument Types = method . getGenericParameterTypes ( ) ;
Assert . isTrue ( args . length = = methodArgument Types . length , "Argument array does not match parameter count" ) ;
Type [ ] methodParameter Types = method . getGenericParameterTypes ( ) ;
Assert . isTrue ( args . length = = methodParameter Types . length , "Argument array does not match parameter count" ) ;
// Ensure that the type variable (e.g., T) is declared directly on the method
// itself (e.g., via <T>), not on the enclosing class or interface.
@ -209,17 +210,33 @@ abstract class AutowireUtils {
@@ -209,17 +210,33 @@ abstract class AutowireUtils {
}
if ( locallyDeclaredTypeVariableMatchesReturnType ) {
for ( int i = 0 ; i < methodArgumentTypes . length ; i + + ) {
Type currentMethodArgumentType = methodArgumentTypes [ i ] ;
if ( currentMethodArgumentType . equals ( genericReturnType ) ) {
return args [ i ] . getClass ( ) ;
for ( int i = 0 ; i < methodParameterTypes . length ; i + + ) {
Type methodParameterType = methodParameterTypes [ i ] ;
Object arg = args [ i ] ;
if ( methodParameterType . equals ( genericReturnType ) ) {
if ( arg instanceof TypedStringValue ) {
TypedStringValue typedValue = ( ( TypedStringValue ) arg ) ;
if ( typedValue . hasTargetType ( ) ) {
return typedValue . getTargetType ( ) ;
}
try {
return typedValue . resolveTargetType ( classLoader ) ;
}
catch ( ClassNotFoundException ex ) {
throw new IllegalStateException ( "Failed to resolve typed value" , ex ) ;
}
}
// Only consider argument type if it is a simple value...
if ( arg ! = null & & ! ( arg instanceof BeanMetadataElement ) ) {
return arg . getClass ( ) ;
}
return method . getReturnType ( ) ;
}
if ( currentMethodArgumentType instanceof ParameterizedType ) {
ParameterizedType parameterizedType = ( ParameterizedType ) currentMethodArgumentType ;
else if ( methodParameter Type instanceof ParameterizedType ) {
ParameterizedType parameterizedType = ( ParameterizedType ) methodParameter Type;
Type [ ] actualTypeArguments = parameterizedType . getActualTypeArguments ( ) ;
for ( Type typeArg : actualTypeArguments ) {
if ( typeArg . equals ( genericReturnType ) ) {
Object arg = args [ i ] ;
if ( arg instanceof Class ) {
return ( Class < ? > ) arg ;
}
@ -229,7 +246,11 @@ abstract class AutowireUtils {
@@ -229,7 +246,11 @@ abstract class AutowireUtils {
className = ( String ) arg ;
}
else if ( arg instanceof TypedStringValue ) {
className = ( ( TypedStringValue ) arg ) . getValue ( ) ;
TypedStringValue typedValue = ( ( TypedStringValue ) arg ) ;
String targetTypeName = typedValue . getTargetTypeName ( ) ;
if ( targetTypeName = = null | | Class . class . getName ( ) . equals ( targetTypeName ) ) {
className = typedValue . getValue ( ) ;
}
}
if ( className ! = null ) {
try {
@ -240,11 +261,9 @@ abstract class AutowireUtils {
@@ -240,11 +261,9 @@ abstract class AutowireUtils {
"Could not resolve specified class name argument [" + arg + "]" , ex ) ;
}
}
else {
// Consider adding logic to determine the class of the typeArg, if possible.
// For now, just fall back...
return method . getReturnType ( ) ;
}
// Consider adding logic to determine the class of the typeArg, if possible.
// For now, just fall back...
return method . getReturnType ( ) ;
}
}
}