diff --git a/org.springframework.context/src/main/java/org/springframework/context/ConfigurableApplicationContext.java b/org.springframework.context/src/main/java/org/springframework/context/ConfigurableApplicationContext.java
index 27407621e3..ad56ae9a25 100644
--- a/org.springframework.context/src/main/java/org/springframework/context/ConfigurableApplicationContext.java
+++ b/org.springframework.context/src/main/java/org/springframework/context/ConfigurableApplicationContext.java
@@ -99,8 +99,8 @@ public interface ConfigurableApplicationContext extends ApplicationContext, Life
* Add a new ApplicationListener that will be notified on context events
* such as context refresh and context shutdown.
*
Note that any ApplicationListener registered here will be applied
- * on refresh of this context. If a listener is added after the initial
- * refresh, it will be applied on next refresh of the context.
+ * on refresh if the context is not active yet, or on the fly with the
+ * current event multicaster in case of a context that is already active.
* @param listener the ApplicationListener to register
* @see org.springframework.context.event.ContextRefreshedEvent
* @see org.springframework.context.event.ContextClosedEvent
diff --git a/org.springframework.context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java b/org.springframework.context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java
index 4a91e556e3..82a412d776 100644
--- a/org.springframework.context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java
+++ b/org.springframework.context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java
@@ -20,11 +20,14 @@ import java.io.IOException;
import java.lang.annotation.Annotation;
import java.security.AccessControlException;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Date;
import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -193,7 +196,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
private ApplicationEventMulticaster applicationEventMulticaster;
/** Statically specified listeners */
- private List applicationListeners = new ArrayList();
+ private Set applicationListeners = new LinkedHashSet();
/**
@@ -362,13 +365,18 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
}
public void addApplicationListener(ApplicationListener listener) {
- this.applicationListeners.add(listener);
+ if (isActive()) {
+ addListener(listener);
+ }
+ else {
+ this.applicationListeners.add(listener);
+ }
}
/**
* Return the list of statically specified ApplicationListeners.
*/
- public List getApplicationListeners() {
+ public Collection getApplicationListeners() {
return this.applicationListeners;
}
@@ -817,7 +825,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let post-processors apply to them!
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
- for (final String lisName : listenerBeanNames) {
+ for (String lisName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(lisName);
}
}
diff --git a/org.springframework.context/src/main/java/org/springframework/context/support/ApplicationContextAwareProcessor.java b/org.springframework.context/src/main/java/org/springframework/context/support/ApplicationContextAwareProcessor.java
index 129d679db7..45f12067b3 100644
--- a/org.springframework.context/src/main/java/org/springframework/context/support/ApplicationContextAwareProcessor.java
+++ b/org.springframework.context/src/main/java/org/springframework/context/support/ApplicationContextAwareProcessor.java
@@ -19,11 +19,18 @@ package org.springframework.context.support;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedAction;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
-import org.springframework.beans.factory.config.BeanPostProcessor;
+import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor;
+import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEventPublisherAware;
+import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.ResourceLoaderAware;
@@ -48,10 +55,14 @@ import org.springframework.context.ResourceLoaderAware;
* @see org.springframework.context.ApplicationContextAware
* @see org.springframework.context.support.AbstractApplicationContext#refresh()
*/
-class ApplicationContextAwareProcessor implements BeanPostProcessor {
+class ApplicationContextAwareProcessor implements MergedBeanDefinitionPostProcessor {
+
+ private final Log logger = LogFactory.getLog(getClass());
private final ConfigurableApplicationContext applicationContext;
+ private final Map singletonNames = new ConcurrentHashMap();
+
/**
* Create a new ApplicationContextAwareProcessor for the given context.
@@ -61,7 +72,13 @@ class ApplicationContextAwareProcessor implements BeanPostProcessor {
}
- public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
+ public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class beanType, String beanName) {
+ if (!this.applicationContext.containsBean(beanName) && beanDefinition.isSingleton()) {
+ this.singletonNames.put(beanName, Boolean.TRUE);
+ }
+ }
+
+ public Object postProcessBeforeInitialization(final Object bean, final String beanName) throws BeansException {
AccessControlContext acc = null;
if (System.getSecurityManager() != null &&
@@ -73,19 +90,19 @@ class ApplicationContextAwareProcessor implements BeanPostProcessor {
if (acc != null) {
AccessController.doPrivileged(new PrivilegedAction