Skip to content

Commit 20c688e

Browse files
kriegaexjhoeller
authored andcommitted
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 86d52a6 commit 20c688e

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

0 commit comments

Comments
 (0)