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 fa69647305a..30e69398fa7 100644 --- a/spring-core/src/main/java/org/springframework/core/ResolvableType.java +++ b/spring-core/src/main/java/org/springframework/core/ResolvableType.java @@ -334,7 +334,7 @@ public class ResolvableType implements Serializable { return otherBounds.isAssignableFrom(this, matchedBefore); } else if (!strict) { - return (matchedBefore != null ? otherBounds.equalsType(this) : + return (matchedBefore != null ? otherBounds.equalsType(this, matchedBefore) : otherBounds.isAssignableTo(this, matchedBefore)); } else { @@ -1775,11 +1775,13 @@ public class ResolvableType implements Serializable { * Return {@code true} if these bounds are equal to the specified type. * @param type the type to test against * @return {@code true} if these bounds are equal to the type - * @since 6.2.3 + * @since 6.2.4 */ - public boolean equalsType(ResolvableType type) { + public boolean equalsType(ResolvableType type, @Nullable Map matchedBefore) { for (ResolvableType bound : this.bounds) { - if (!type.equalsType(bound)) { + if (this.kind == Kind.UPPER && bound.hasUnresolvableGenerics() ? + !type.isAssignableFrom(bound, true, matchedBefore, false) : + !type.equalsType(bound)) { return false; } } 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 dcfc31a897e..f46531fb374 100644 --- a/spring-core/src/test/java/org/springframework/core/ResolvableTypeTests.java +++ b/spring-core/src/test/java/org/springframework/core/ResolvableTypeTests.java @@ -1527,6 +1527,12 @@ class ResolvableTypeTests { assertThat(repository3.isAssignableFromResolvedPart(repository2)).isTrue(); } + @Test + void gh34541() throws Exception { + ResolvableType typeWithGenerics = ResolvableType.forField(getClass().getDeclaredField("paymentCreator")); + assertThat(typeWithGenerics.isAssignableFrom(PaymentCreator.class)).isTrue(); + } + private ResolvableType testSerialization(ResolvableType type) throws Exception { ByteArrayOutputStream bos = new ByteArrayOutputStream(); @@ -1928,6 +1934,18 @@ class ResolvableTypeTests { } + PaymentCreator> paymentCreator; + + static class PaymentCreator> { + } + + static class PaymentCreatorParameter { + } + + abstract static class Payment { + } + + private static class ResolvableTypeAssert extends AbstractAssert{ public ResolvableTypeAssert(ResolvableType actual) {