Skip to content

Commit 0dba415

Browse files
committed
Avoid duplicate application listeners (proxy vs. proxy target)
In AbstractApplicationEventMulticaster.retrieveApplicationListeners, despite best efforts to avoid it, unwrapped proxies (singleton targets) can end up in the list of programmatically registered listeners. In order to avoid duplicates, we need to find and replace them by their proxy counterparts, because if both a proxy and its target end up in 'allListeners', listeners will fire twice. Fixes #28283.
1 parent 5367d96 commit 0dba415

File tree

1 file changed

+18
-0
lines changed

1 file changed

+18
-0
lines changed

spring-context/src/main/java/org/springframework/context/event/AbstractApplicationEventMulticaster.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,24 @@ private Collection<ApplicationListener<?>> retrieveApplicationListeners(
262262
if (supportsEvent(beanFactory, listenerBeanName, eventType)) {
263263
ApplicationListener<?> listener =
264264
beanFactory.getBean(listenerBeanName, ApplicationListener.class);
265+
266+
// Despite best efforts to avoid it, unwrapped proxies (singleton targets) can end up in the
267+
// list of programmatically registered listeners. In order to avoid duplicates, we need to find
268+
// and replace them by their proxy counterparts, because if both a proxy and its target end up
269+
// in 'allListeners', listeners will fire twice.
270+
ApplicationListener<?> unwrappedListener =
271+
(ApplicationListener<?>) AopProxyUtils.getSingletonTarget(listener);
272+
if (listener != unwrappedListener) {
273+
if (filteredListeners != null && filteredListeners.contains(unwrappedListener)) {
274+
filteredListeners.remove(unwrappedListener);
275+
filteredListeners.add(listener);
276+
}
277+
if (allListeners.contains(unwrappedListener)) {
278+
allListeners.remove(unwrappedListener);
279+
allListeners.add(listener);
280+
}
281+
}
282+
265283
if (!allListeners.contains(listener) && supportsEvent(listener, eventType, sourceType)) {
266284
if (retriever != null) {
267285
if (beanFactory.isSingleton(listenerBeanName)) {

0 commit comments

Comments
 (0)