From 714c3c59eb23d3eb9969465717a0258ac2f7b6a5 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 21 Jun 2023 13:15:35 +0200 Subject: [PATCH] Accept unresolvable generics as long as raw event class matches Closes gh-30712 --- .../event/ApplicationListenerMethodAdapter.java | 9 +++++++-- .../ApplicationListenerMethodAdapterTests.java | 13 +++++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/context/event/ApplicationListenerMethodAdapter.java b/spring-context/src/main/java/org/springframework/context/event/ApplicationListenerMethodAdapter.java index f61a767bcc8f..7079b69d4cd9 100644 --- a/spring-context/src/main/java/org/springframework/context/event/ApplicationListenerMethodAdapter.java +++ b/spring-context/src/main/java/org/springframework/context/event/ApplicationListenerMethodAdapter.java @@ -168,12 +168,17 @@ public void onApplicationEvent(ApplicationEvent event) { @Override public boolean supportsEventType(ResolvableType eventType) { for (ResolvableType declaredEventType : this.declaredEventTypes) { - if (declaredEventType.isAssignableFrom(eventType)) { + if (eventType.hasUnresolvableGenerics() ? + declaredEventType.toClass().isAssignableFrom(eventType.toClass()) : + declaredEventType.isAssignableFrom(eventType)) { return true; } if (PayloadApplicationEvent.class.isAssignableFrom(eventType.toClass())) { + if (eventType.hasUnresolvableGenerics()) { + return true; + } ResolvableType payloadType = eventType.as(PayloadApplicationEvent.class).getGeneric(); - if (declaredEventType.isAssignableFrom(payloadType) || eventType.hasUnresolvableGenerics()) { + if (declaredEventType.isAssignableFrom(payloadType)) { return true; } } diff --git a/spring-context/src/test/java/org/springframework/context/event/ApplicationListenerMethodAdapterTests.java b/spring-context/src/test/java/org/springframework/context/event/ApplicationListenerMethodAdapterTests.java index edc698297421..858009aabfb1 100644 --- a/spring-context/src/test/java/org/springframework/context/event/ApplicationListenerMethodAdapterTests.java +++ b/spring-context/src/test/java/org/springframework/context/event/ApplicationListenerMethodAdapterTests.java @@ -47,6 +47,8 @@ /** * @author Stephane Nicoll + * @author Juergen Hoeller + * @author Simon Baslé */ public class ApplicationListenerMethodAdapterTests extends AbstractApplicationEventListenerTests { @@ -81,6 +83,13 @@ public void genericListenerWrongParameterizedType() { supportsEventType(false, method, ResolvableType.forClassWithGenerics(GenericTestEvent.class, Long.class)); } + @Test + public void genericListenerWithUnresolvedGenerics() { + Method method = ReflectionUtils.findMethod( + SampleEvents.class, "handleGenericString", GenericTestEvent.class); + supportsEventType(true, method, ResolvableType.forClass(GenericTestEvent.class)); + } + @Test public void listenerWithPayloadAndGenericInformation() { Method method = ReflectionUtils.findMethod(SampleEvents.class, "handleString", String.class); @@ -347,7 +356,7 @@ void genericPayloadDoesNotSupportArbitraryGenericEventType() throws Exception { var adapter = new ApplicationListenerMethodAdapter(null, ApplicationListenerMethodAdapterTests.class, method); assertThat(adapter.supportsEventType(ResolvableType.forClass(EntityWrapper.class))) - .as("handleGenericStringPayload(EntityWrapper) with EntityWrapper").isFalse(); + .as("handleGenericStringPayload(EntityWrapper) with EntityWrapper").isTrue(); assertThat(adapter.supportsEventType(ResolvableType.forClassWithGenerics(EntityWrapper.class, Integer.class))) .as("handleGenericStringPayload(EntityWrapper) with EntityWrapper").isFalse(); assertThat(adapter.supportsEventType(ResolvableType.forClassWithGenerics(EntityWrapper.class, String.class))) @@ -378,7 +387,7 @@ void genericApplicationEventSupportsSpecificType() throws Exception { var adapter = new ApplicationListenerMethodAdapter(null, ApplicationListenerMethodAdapterTests.class, method); assertThat(adapter.supportsEventType(ResolvableType.forClass(GenericTestEvent.class))) - .as("handleGenericString(GenericTestEvent) with GenericTestEvent").isFalse(); + .as("handleGenericString(GenericTestEvent) with GenericTestEvent").isTrue(); assertThat(adapter.supportsEventType(ResolvableType.forClassWithGenerics(GenericTestEvent.class, Integer.class))) .as("handleGenericString(GenericTestEvent) with GenericTestEvent").isFalse(); assertThat(adapter.supportsEventType(ResolvableType.forClassWithGenerics(GenericTestEvent.class, String.class)))