From 63c8e7cb5d08dab01a8380ced38c3da3dbdfa3cf Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Thu, 6 Mar 2025 15:44:12 +0100 Subject: [PATCH] Restore lenient matching of unresolved nested bound Closes gh-34541 --- .../springframework/core/ResolvableType.java | 10 ++++++---- .../core/ResolvableTypeTests.java | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+), 4 deletions(-) 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 76ca26f17dd..03209325493 100644 --- a/spring-core/src/main/java/org/springframework/core/ResolvableType.java +++ b/spring-core/src/main/java/org/springframework/core/ResolvableType.java @@ -343,7 +343,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 { @@ -1794,11 +1794,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) {