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.
This commit is contained in:
committed by
Juergen Hoeller
parent
86d52a677a
commit
20c688e68d
@@ -263,6 +263,24 @@ public abstract class AbstractApplicationEventMulticaster
|
||||
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)) {
|
||||
|
||||
Reference in New Issue
Block a user