diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java index 0e74e058583..30408822f71 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java @@ -576,35 +576,36 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto if (this.logger.isInfoEnabled()) { this.logger.info("Pre-instantiating singletons in " + this); } + List beanNames; synchronized (this.beanDefinitionMap) { // Iterate over a copy to allow for init methods which in turn register new bean definitions. // While this may not be part of the regular factory bootstrap, it does otherwise work fine. - List beanNames = new ArrayList(this.beanDefinitionNames); - for (String beanName : beanNames) { - RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); - if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { - if (isFactoryBean(beanName)) { - final FactoryBean factory = (FactoryBean) getBean(FACTORY_BEAN_PREFIX + beanName); - boolean isEagerInit; - if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { - isEagerInit = AccessController.doPrivileged(new PrivilegedAction() { - public Boolean run() { - return ((SmartFactoryBean) factory).isEagerInit(); - } - }, getAccessControlContext()); - } - else { - isEagerInit = (factory instanceof SmartFactoryBean && - ((SmartFactoryBean) factory).isEagerInit()); - } - if (isEagerInit) { - getBean(beanName); - } + beanNames = new ArrayList(this.beanDefinitionNames); + } + for (String beanName : beanNames) { + RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); + if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { + if (isFactoryBean(beanName)) { + final FactoryBean factory = (FactoryBean) getBean(FACTORY_BEAN_PREFIX + beanName); + boolean isEagerInit; + if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { + isEagerInit = AccessController.doPrivileged(new PrivilegedAction() { + public Boolean run() { + return ((SmartFactoryBean) factory).isEagerInit(); + } + }, getAccessControlContext()); } else { + isEagerInit = (factory instanceof SmartFactoryBean && + ((SmartFactoryBean) factory).isEagerInit()); + } + if (isEagerInit) { getBean(beanName); } } + else { + getBean(beanName); + } } } } @@ -650,9 +651,9 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto this.frozenBeanDefinitionNames = null; } this.beanDefinitionMap.put(beanName, beanDefinition); - - resetBeanDefinition(beanName); } + + resetBeanDefinition(beanName); } public void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException { @@ -668,9 +669,9 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto } this.beanDefinitionNames.remove(beanName); this.frozenBeanDefinitionNames = null; - - resetBeanDefinition(beanName); } + + resetBeanDefinition(beanName); } /** @@ -685,9 +686,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto // Remove corresponding bean from singleton cache, if any. Shouldn't usually // be necessary, rather just meant for overriding a context's default beans // (e.g. the default StaticMessageSource in a StaticApplicationContext). - synchronized (getSingletonMutex()) { - destroySingleton(beanName); - } + destroySingleton(beanName); // Remove any assumptions about by-type mappings this.singletonBeanNamesByType.clear(); 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 b6d363f3ad1..43564d4d51b 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 @@ -447,11 +447,12 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements this.singletonsCurrentlyInDestruction = true; } + String[] disposableBeanNames; synchronized (this.disposableBeans) { - String[] disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet()); - for (int i = disposableBeanNames.length - 1; i >= 0; i--) { - destroySingleton(disposableBeanNames[i]); - } + disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet()); + } + for (int i = disposableBeanNames.length - 1; i >= 0; i--) { + destroySingleton(disposableBeanNames[i]); } this.containedBeanMap.clear(); 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 0ff7a78d46d..40ebd207596 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-2010 the original author or authors. + * Copyright 2002-2012 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. @@ -113,7 +113,9 @@ public abstract class AbstractApplicationEventMulticaster implements Application * @see org.springframework.context.ApplicationListener */ protected Collection getApplicationListeners() { - return this.defaultRetriever.getApplicationListeners(); + synchronized (this.defaultRetriever) { + return this.defaultRetriever.getApplicationListeners(); + } } /** @@ -135,26 +137,30 @@ public abstract class AbstractApplicationEventMulticaster implements Application else { retriever = new ListenerRetriever(true); LinkedList allListeners = new LinkedList(); + Set listeners; + Set listenerBeans; synchronized (this.defaultRetriever) { - for (ApplicationListener listener : this.defaultRetriever.applicationListeners) { - if (supportsEvent(listener, eventType, sourceType)) { - retriever.applicationListeners.add(listener); + listeners = new LinkedHashSet(this.defaultRetriever.applicationListeners); + listenerBeans = new LinkedHashSet(this.defaultRetriever.applicationListenerBeans); + } + for (ApplicationListener listener : listeners) { + if (supportsEvent(listener, eventType, sourceType)) { + retriever.applicationListeners.add(listener); + allListeners.add(listener); + } + } + if (!listenerBeans.isEmpty()) { + BeanFactory beanFactory = getBeanFactory(); + for (String listenerBeanName : listenerBeans) { + ApplicationListener listener = beanFactory.getBean(listenerBeanName, ApplicationListener.class); + if (!allListeners.contains(listener) && supportsEvent(listener, eventType, sourceType)) { + retriever.applicationListenerBeans.add(listenerBeanName); allListeners.add(listener); } } - if (!this.defaultRetriever.applicationListenerBeans.isEmpty()) { - BeanFactory beanFactory = getBeanFactory(); - for (String listenerBeanName : this.defaultRetriever.applicationListenerBeans) { - ApplicationListener listener = beanFactory.getBean(listenerBeanName, ApplicationListener.class); - if (!allListeners.contains(listener) && supportsEvent(listener, eventType, sourceType)) { - retriever.applicationListenerBeans.add(listenerBeanName); - allListeners.add(listener); - } - } - } - OrderComparator.sort(allListeners); - this.retrieverCache.put(cacheKey, retriever); } + OrderComparator.sort(allListeners); + this.retrieverCache.put(cacheKey, retriever); return allListeners; } }