From b387d9bf106d8b53e8a5232bf09421063c9892e3 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 18 Jul 2023 13:27:15 +0200 Subject: [PATCH] MethodIntrospector handles overriding bridge method correctly Closes gh-30906 (cherry picked from commit 616f728afa272270d1a606e61b515b1bb9339064) --- .../AnnotationDrivenEventListenerTests.java | 33 +++++++++++++------ .../core/MethodIntrospector.java | 5 +-- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/spring-context/src/test/java/org/springframework/context/event/AnnotationDrivenEventListenerTests.java b/spring-context/src/test/java/org/springframework/context/event/AnnotationDrivenEventListenerTests.java index c493f075b1a..4374b4210d5 100644 --- a/spring-context/src/test/java/org/springframework/context/event/AnnotationDrivenEventListenerTests.java +++ b/spring-context/src/test/java/org/springframework/context/event/AnnotationDrivenEventListenerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2023 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. @@ -164,12 +164,12 @@ class AnnotationDrivenEventListenerTests { ContextEventListener listener = this.context.getBean(ContextEventListener.class); List events = this.eventCollector.getEvents(listener); - assertThat(events.size()).as("Wrong number of initial context events").isEqualTo(1); + assertThat(events).as("Wrong number of initial context events").hasSize(1); assertThat(events.get(0).getClass()).isEqualTo(ContextRefreshedEvent.class); this.context.stop(); List eventsAfterStop = this.eventCollector.getEvents(listener); - assertThat(eventsAfterStop.size()).as("Wrong number of context events on shutdown").isEqualTo(2); + assertThat(eventsAfterStop).as("Wrong number of context events on shutdown").hasSize(2); assertThat(eventsAfterStop.get(1).getClass()).isEqualTo(ContextStoppedEvent.class); this.eventCollector.assertTotalEventsCount(2); } @@ -334,7 +334,7 @@ class AnnotationDrivenEventListenerTests { load(ScopedProxyTestBean.class); SimpleService proxy = this.context.getBean(SimpleService.class); - assertThat(proxy instanceof Advised).as("bean should be a proxy").isTrue(); + assertThat(proxy).as("bean should be a proxy").isInstanceOf(Advised.class); this.eventCollector.assertNoEventReceived(proxy.getId()); this.context.publishEvent(new ContextRefreshedEvent(this.context)); @@ -351,7 +351,7 @@ class AnnotationDrivenEventListenerTests { load(AnnotatedProxyTestBean.class); AnnotatedSimpleService proxy = this.context.getBean(AnnotatedSimpleService.class); - assertThat(proxy instanceof Advised).as("bean should be a proxy").isTrue(); + assertThat(proxy).as("bean should be a proxy").isInstanceOf(Advised.class); this.eventCollector.assertNoEventReceived(proxy.getId()); this.context.publishEvent(new ContextRefreshedEvent(this.context)); @@ -517,7 +517,6 @@ class AnnotationDrivenEventListenerTests { ReplyEventListener replyEventListener = this.context.getBean(ReplyEventListener.class); TestEventListener listener = this.context.getBean(TestEventListener.class); - this.eventCollector.assertNoEventReceived(listener); this.eventCollector.assertNoEventReceived(replyEventListener); this.context.publishEvent(event); @@ -634,6 +633,17 @@ class AnnotationDrivenEventListenerTests { assertThat(listener.order).contains("first", "second", "third"); } + @Test + void publicSubclassWithInheritedEventListener() { + load(PublicSubclassWithInheritedEventListener.class); + TestEventListener listener = this.context.getBean(PublicSubclassWithInheritedEventListener.class); + + this.eventCollector.assertNoEventReceived(listener); + this.context.publishEvent("test"); + this.eventCollector.assertEvent(listener, "test"); + this.eventCollector.assertTotalEventsCount(1); + } + @Test @Disabled // SPR-15122 void listenersReceiveEarlyEvents() { load(EventOnPostConstruct.class, OrderedTestListener.class); @@ -646,7 +656,7 @@ class AnnotationDrivenEventListenerTests { void missingListenerBeanIgnored() { load(MissingEventListener.class); context.getBean(UseMissingEventListener.class); - context.getBean(ApplicationEventMulticaster.class).multicastEvent(new TestEvent(this)); + context.publishEvent(new TestEvent(this)); } @@ -753,7 +763,6 @@ class AnnotationDrivenEventListenerTests { public void handleContextEvent(ApplicationContextEvent event) { collectEvent(event); } - } @@ -980,7 +989,6 @@ class AnnotationDrivenEventListenerTests { } - @EventListener @Retention(RetentionPolicy.RUNTIME) public @interface ConditionalEvent { @@ -1032,7 +1040,7 @@ class AnnotationDrivenEventListenerTests { } - @Configuration + @Component static class OrderedTestListener extends TestEventListener { public final List order = new ArrayList<>(); @@ -1056,6 +1064,11 @@ class AnnotationDrivenEventListenerTests { } + @Component + public static class PublicSubclassWithInheritedEventListener extends TestEventListener { + } + + static class EventOnPostConstruct { @Autowired diff --git a/spring-core/src/main/java/org/springframework/core/MethodIntrospector.java b/spring-core/src/main/java/org/springframework/core/MethodIntrospector.java index 2947945cc48..9f905cbda47 100644 --- a/spring-core/src/main/java/org/springframework/core/MethodIntrospector.java +++ b/spring-core/src/main/java/org/springframework/core/MethodIntrospector.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2023 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. @@ -74,7 +74,8 @@ public final class MethodIntrospector { T result = metadataLookup.inspect(specificMethod); if (result != null) { Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(specificMethod); - if (bridgedMethod == specificMethod || metadataLookup.inspect(bridgedMethod) == null) { + if (bridgedMethod == specificMethod || bridgedMethod == method || + metadataLookup.inspect(bridgedMethod) == null) { methodMap.put(specificMethod, result); } }