diff --git a/spring-core/src/main/java/org/springframework/core/ResolvableType.java b/spring-core/src/main/java/org/springframework/core/ResolvableType.java index 720e4eb56e7..994a395cf7d 100644 --- a/spring-core/src/main/java/org/springframework/core/ResolvableType.java +++ b/spring-core/src/main/java/org/springframework/core/ResolvableType.java @@ -873,6 +873,12 @@ public class ResolvableType implements Serializable { return forType(ownerType, this.variableResolver).resolveVariable(variable); } } + if (this.type instanceof WildcardType) { + ResolvableType resolved = resolveType().resolveVariable(variable); + if (resolved != null) { + return resolved; + } + } if (this.variableResolver != null) { return this.variableResolver.resolveVariable(variable); } diff --git a/spring-core/src/test/java/org/springframework/core/ResolvableTypeTests.java b/spring-core/src/test/java/org/springframework/core/ResolvableTypeTests.java index 27182ecfb16..7a781bb7e7d 100644 --- a/spring-core/src/test/java/org/springframework/core/ResolvableTypeTests.java +++ b/spring-core/src/test/java/org/springframework/core/ResolvableTypeTests.java @@ -688,6 +688,13 @@ class ResolvableTypeTests { assertThat(type.resolve()).isEqualTo(CharSequence.class); } + + @Test + void resolveBoundedTypeVariableWildcardResult() throws Exception { + ResolvableType type = ResolvableType.forMethodReturnType(Methods.class.getMethod("boundedTypeVaraibleWildcardResult")); + assertThat(type.getGeneric(1).asCollection().resolveGeneric()).isEqualTo(CharSequence.class); + } + @Test void resolveVariableNotFound() throws Exception { ResolvableType type = ResolvableType.forMethodReturnType(Methods.class.getMethod("typedReturn")); @@ -1417,6 +1424,8 @@ class ResolvableTypeTests { R boundedTypeVaraibleResult(); + Map> boundedTypeVaraibleWildcardResult(); + void nested(Map, Map> p); void typedParameter(T p);