From e1602f7f83ded6438ce1307605d4de2366cfb8f7 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 26 Mar 2014 15:29:50 +0100 Subject: [PATCH] AbstractApplicationEventMulticaster only caches if event type and source type are cache-safe Issue: SPR-11606 (cherry picked from commit 3388573) --- .../AbstractApplicationEventMulticaster.java | 29 +++++++++++++++---- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/context/event/AbstractApplicationEventMulticaster.java b/spring-context/src/main/java/org/springframework/context/event/AbstractApplicationEventMulticaster.java index f14f164ce6..abb46885f8 100644 --- a/spring-context/src/main/java/org/springframework/context/event/AbstractApplicationEventMulticaster.java +++ b/spring-context/src/main/java/org/springframework/context/event/AbstractApplicationEventMulticaster.java @@ -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 retrieverCache = new ConcurrentHashMap(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 eventType, Class sourceType) {