Explicitly replace target ApplicationListener with singleton proxy, if any (avoiding double registration/invocation)

Issue: SPR-15452
This commit is contained in:
Juergen Hoeller
2017-04-15 14:10:28 +02:00
parent 3efb76c852
commit 9abf249cee
3 changed files with 54 additions and 11 deletions

View File

@@ -23,6 +23,7 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.aop.framework.AopProxyUtils;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
@@ -98,6 +99,12 @@ public abstract class AbstractApplicationEventMulticaster
@Override
public void addApplicationListener(ApplicationListener<?> listener) {
synchronized (this.retrievalMutex) {
// Explicitly remove target for a proxy, if registered already,
// in order to avoid double invocations of the same listener.
Object singletonTarget = AopProxyUtils.getSingletonTarget(listener);
if (singletonTarget instanceof ApplicationListener) {
this.defaultRetriever.applicationListeners.remove(singletonTarget);
}
this.defaultRetriever.applicationListeners.add(listener);
this.retrieverCache.clear();
}