Skip to content

Commit

Permalink
Avoid duplicate application listeners (proxy vs. proxy target)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
kriegaex authored and jhoeller committed Oct 10, 2023
1 parent 86d52a6 commit 20c688e
Showing 1 changed file with 18 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,24 @@ private Collection<ApplicationListener<?>> retrieveApplicationListeners(
if (supportsEvent(beanFactory, listenerBeanName, eventType)) {
ApplicationListener<?> listener =
beanFactory.getBean(listenerBeanName, ApplicationListener.class);

// 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.
ApplicationListener<?> unwrappedListener =
(ApplicationListener<?>) AopProxyUtils.getSingletonTarget(listener);
if (listener != unwrappedListener) {
if (filteredListeners != null && filteredListeners.contains(unwrappedListener)) {
filteredListeners.remove(unwrappedListener);
filteredListeners.add(listener);
}
if (allListeners.contains(unwrappedListener)) {
allListeners.remove(unwrappedListener);
allListeners.add(listener);
}
}

if (!allListeners.contains(listener) && supportsEvent(listener, eventType, sourceType)) {
if (retriever != null) {
if (beanFactory.isSingleton(listenerBeanName)) {
Expand Down

0 comments on commit 20c688e

Please sign in to comment.