Avoid mismatch between cached top-level versus nested parameter type

Issue: SPR-13755
This commit is contained in:
Juergen Hoeller 2015-12-03 12:53:18 +01:00
parent f5e681e6e6
commit c909789ea9
2 changed files with 31 additions and 18 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -51,28 +51,28 @@ public abstract class GenericTypeResolver {
/**
* Determine the target type for the given parameter specification.
* @param methodParam the method parameter specification
* @param methodParameter the method parameter specification
* @return the corresponding generic parameter type
* @deprecated as of Spring 4.0, use {@link MethodParameter#getGenericParameterType()}
*/
@Deprecated
public static Type getTargetType(MethodParameter methodParam) {
Assert.notNull(methodParam, "MethodParameter must not be null");
return methodParam.getGenericParameterType();
public static Type getTargetType(MethodParameter methodParameter) {
Assert.notNull(methodParameter, "MethodParameter must not be null");
return methodParameter.getGenericParameterType();
}
/**
* Determine the target type for the given generic parameter type.
* @param methodParam the method parameter specification
* @param clazz the class to resolve type variables against
* @param methodParameter the method parameter specification
* @param implementationClass the class to resolve type variables against
* @return the corresponding generic parameter or return type
*/
public static Class<?> resolveParameterType(MethodParameter methodParam, Class<?> clazz) {
Assert.notNull(methodParam, "MethodParameter must not be null");
Assert.notNull(clazz, "Class must not be null");
methodParam.setContainingClass(clazz);
methodParam.setParameterType(ResolvableType.forMethodParameter(methodParam).resolve());
return methodParam.getParameterType();
public static Class<?> resolveParameterType(MethodParameter methodParameter, Class<?> implementationClass) {
Assert.notNull(methodParameter, "MethodParameter must not be null");
Assert.notNull(implementationClass, "Class must not be null");
methodParameter.setContainingClass(implementationClass);
ResolvableType.resolveMethodParameter(methodParameter);
return methodParameter.getParameterType();
}
/**

View File

@ -1219,11 +1219,11 @@ public class ResolvableType implements Serializable {
*/
public static ResolvableType forMethodParameter(MethodParameter methodParameter, ResolvableType implementationType) {
Assert.notNull(methodParameter, "MethodParameter must not be null");
implementationType = (implementationType == null ? forType(methodParameter.getContainingClass()) : implementationType);
implementationType = (implementationType != null ? implementationType :
forType(methodParameter.getContainingClass()));
ResolvableType owner = implementationType.as(methodParameter.getDeclaringClass());
return forType(null, new MethodParameterTypeProvider(methodParameter),
owner.asVariableResolver()).getNested(methodParameter.getNestingLevel(),
methodParameter.typeIndexesPerLevel);
return forType(null, new MethodParameterTypeProvider(methodParameter), owner.asVariableResolver()).
getNested(methodParameter.getNestingLevel(), methodParameter.typeIndexesPerLevel);
}
/**
@ -1241,13 +1241,26 @@ public class ResolvableType implements Serializable {
getNested(methodParameter.getNestingLevel(), methodParameter.typeIndexesPerLevel);
}
/**
* Resolve the top-level parameter type of the given {@code MethodParameter}.
* @param methodParameter the method parameter to resolve
* @since 4.1.9
* @see MethodParameter#setParameterType
*/
static void resolveMethodParameter(MethodParameter methodParameter) {
Assert.notNull(methodParameter, "MethodParameter must not be null");
ResolvableType owner = forType(methodParameter.getContainingClass()).as(methodParameter.getDeclaringClass());
methodParameter.setParameterType(
forType(null, new MethodParameterTypeProvider(methodParameter), owner.asVariableResolver()).resolve());
}
/**
* Return a {@link ResolvableType} as a array of the specified {@code componentType}.
* @param componentType the component type
* @return a {@link ResolvableType} as an array of the specified component type
*/
public static ResolvableType forArrayComponent(ResolvableType componentType) {
Assert.notNull(componentType, "componentType must not be null");
Assert.notNull(componentType, "Component type must not be null");
Class<?> arrayClass = Array.newInstance(componentType.resolve(), 0).getClass();
return new ResolvableType(arrayClass, null, null, componentType);
}