diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/config/SingletonBeanRegistry.java b/spring-beans/src/main/java/org/springframework/beans/factory/config/SingletonBeanRegistry.java index 79d0234c37d..e2188050f17 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/config/SingletonBeanRegistry.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/config/SingletonBeanRegistry.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2015 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. @@ -122,4 +122,11 @@ public interface SingletonBeanRegistry { */ int getSingletonCount(); + /** + * Return the singleton mutex used by this registry (for external collaborators). + * @return the mutex object (never {@code null}) + * @since 4.2 + */ + Object getSingletonMutex(); + } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultSingletonBeanRegistry.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultSingletonBeanRegistry.java index e1790d5bf5d..2077a101bdb 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultSingletonBeanRegistry.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultSingletonBeanRegistry.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2015 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. @@ -607,13 +607,13 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements } /** - * Expose the singleton mutex to subclasses. + * Exposes the singleton mutex to subclasses and external collaborators. *
Subclasses should synchronize on the given Object if they perform
* any sort of extended singleton creation phase. In particular, subclasses
* should not have their own mutexes involved in singleton creation,
* to avoid the potential for deadlocks in lazy-init situations.
*/
- protected final Object getSingletonMutex() {
+ public final Object getSingletonMutex() {
return this.singletonObjects;
}
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 2d857d49c0c..cf1ed74539d 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
@@ -67,10 +67,38 @@ public abstract class AbstractApplicationEventMulticaster
private BeanFactory beanFactory;
+ private Object retrievalMutex = this.defaultRetriever;
+
+
+ @Override
+ public void setBeanClassLoader(ClassLoader classLoader) {
+ this.beanClassLoader = classLoader;
+ }
+
+ @Override
+ public void setBeanFactory(BeanFactory beanFactory) {
+ this.beanFactory = beanFactory;
+ if (beanFactory instanceof ConfigurableBeanFactory) {
+ ConfigurableBeanFactory cbf = (ConfigurableBeanFactory) beanFactory;
+ if (this.beanClassLoader == null) {
+ this.beanClassLoader = cbf.getBeanClassLoader();
+ }
+ this.retrievalMutex = cbf.getSingletonMutex();
+ }
+ }
+
+ private BeanFactory getBeanFactory() {
+ if (this.beanFactory == null) {
+ throw new IllegalStateException("ApplicationEventMulticaster cannot retrieve listener beans " +
+ "because it is not associated with a BeanFactory");
+ }
+ return this.beanFactory;
+ }
+
@Override
public void addApplicationListener(ApplicationListener> listener) {
- synchronized (this.defaultRetriever) {
+ synchronized (this.retrievalMutex) {
this.defaultRetriever.applicationListeners.add(listener);
this.retrieverCache.clear();
}
@@ -78,7 +106,7 @@ public abstract class AbstractApplicationEventMulticaster
@Override
public void addApplicationListenerBean(String listenerBeanName) {
- synchronized (this.defaultRetriever) {
+ synchronized (this.retrievalMutex) {
this.defaultRetriever.applicationListenerBeans.add(listenerBeanName);
this.retrieverCache.clear();
}
@@ -86,7 +114,7 @@ public abstract class AbstractApplicationEventMulticaster
@Override
public void removeApplicationListener(ApplicationListener> listener) {
- synchronized (this.defaultRetriever) {
+ synchronized (this.retrievalMutex) {
this.defaultRetriever.applicationListeners.remove(listener);
this.retrieverCache.clear();
}
@@ -94,7 +122,7 @@ public abstract class AbstractApplicationEventMulticaster
@Override
public void removeApplicationListenerBean(String listenerBeanName) {
- synchronized (this.defaultRetriever) {
+ synchronized (this.retrievalMutex) {
this.defaultRetriever.applicationListenerBeans.remove(listenerBeanName);
this.retrieverCache.clear();
}
@@ -102,34 +130,13 @@ public abstract class AbstractApplicationEventMulticaster
@Override
public void removeAllListeners() {
- synchronized (this.defaultRetriever) {
+ synchronized (this.retrievalMutex) {
this.defaultRetriever.applicationListeners.clear();
this.defaultRetriever.applicationListenerBeans.clear();
this.retrieverCache.clear();
}
}
- @Override
- public void setBeanClassLoader(ClassLoader classLoader) {
- this.beanClassLoader = classLoader;
- }
-
- @Override
- public void setBeanFactory(BeanFactory beanFactory) {
- this.beanFactory = beanFactory;
- if (this.beanClassLoader == null && beanFactory instanceof ConfigurableBeanFactory) {
- this.beanClassLoader = ((ConfigurableBeanFactory) beanFactory).getBeanClassLoader();
- }
- }
-
- private BeanFactory getBeanFactory() {
- if (this.beanFactory == null) {
- throw new IllegalStateException("ApplicationEventMulticaster cannot retrieve listener beans " +
- "because it is not associated with a BeanFactory");
- }
- return this.beanFactory;
- }
-
/**
* Return a Collection containing all ApplicationListeners.
@@ -137,7 +144,7 @@ public abstract class AbstractApplicationEventMulticaster
* @see org.springframework.context.ApplicationListener
*/
protected Collection