AbstractApplicationEventMulticaster only caches if event type and source type are cache-safe
Issue: SPR-11606
(cherry picked from commit 3388573)
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -23,11 +23,14 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.core.OrderComparator;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
@@ -49,13 +52,16 @@ import org.springframework.util.ObjectUtils;
|
||||
* @see #getApplicationListeners(ApplicationEvent)
|
||||
* @see SimpleApplicationEventMulticaster
|
||||
*/
|
||||
public abstract class AbstractApplicationEventMulticaster implements ApplicationEventMulticaster, BeanFactoryAware {
|
||||
public abstract class AbstractApplicationEventMulticaster
|
||||
implements ApplicationEventMulticaster, BeanClassLoaderAware, BeanFactoryAware {
|
||||
|
||||
private final ListenerRetriever defaultRetriever = new ListenerRetriever(false);
|
||||
|
||||
private final Map<ListenerCacheKey, ListenerRetriever> retrieverCache =
|
||||
new ConcurrentHashMap<ListenerCacheKey, ListenerRetriever>(64);
|
||||
|
||||
private ClassLoader beanClassLoader;
|
||||
|
||||
private BeanFactory beanFactory;
|
||||
|
||||
|
||||
@@ -95,8 +101,15 @@ public abstract class AbstractApplicationEventMulticaster implements Application
|
||||
}
|
||||
}
|
||||
|
||||
public final void setBeanFactory(BeanFactory beanFactory) {
|
||||
public void setBeanClassLoader(ClassLoader classLoader) {
|
||||
this.beanClassLoader = classLoader;
|
||||
}
|
||||
|
||||
public void setBeanFactory(BeanFactory beanFactory) {
|
||||
this.beanFactory = beanFactory;
|
||||
if (this.beanClassLoader == null && beanFactory instanceof ConfigurableBeanFactory) {
|
||||
this.beanClassLoader = ((ConfigurableBeanFactory) beanFactory).getBeanClassLoader();
|
||||
}
|
||||
}
|
||||
|
||||
private BeanFactory getBeanFactory() {
|
||||
@@ -162,7 +175,11 @@ public abstract class AbstractApplicationEventMulticaster implements Application
|
||||
}
|
||||
}
|
||||
OrderComparator.sort(allListeners);
|
||||
this.retrieverCache.put(cacheKey, retriever);
|
||||
if (this.beanClassLoader == null ||
|
||||
(ClassUtils.isCacheSafe(eventType, this.beanClassLoader) &&
|
||||
(sourceType == null || ClassUtils.isCacheSafe(sourceType, this.beanClassLoader)))) {
|
||||
this.retrieverCache.put(cacheKey, retriever);
|
||||
}
|
||||
return allListeners;
|
||||
}
|
||||
}
|
||||
@@ -176,8 +193,8 @@ public abstract class AbstractApplicationEventMulticaster implements Application
|
||||
* @param listener the target listener to check
|
||||
* @param eventType the event type to check against
|
||||
* @param sourceType the source type to check against
|
||||
* @return whether the given listener should be included in the
|
||||
* candidates for the given event type
|
||||
* @return whether the given listener should be included in the candidates
|
||||
* for the given event type
|
||||
*/
|
||||
protected boolean supportsEvent(
|
||||
ApplicationListener listener, Class<? extends ApplicationEvent> eventType, Class sourceType) {
|
||||
|
||||
Reference in New Issue
Block a user