diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java index 9e0044c0ee0..57d7cdb1896 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java @@ -30,11 +30,11 @@ import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedHashSet; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanWrapper; @@ -142,16 +142,16 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp private TypeConverter typeConverter; /** String resolvers to apply e.g. to annotation attribute values */ - private final List embeddedValueResolvers = new LinkedList(); + private final List embeddedValueResolvers = new CopyOnWriteArrayList(); /** BeanPostProcessors to apply in createBean */ - private final List beanPostProcessors = new ArrayList(); + private final List beanPostProcessors = new CopyOnWriteArrayList(); /** Indicates whether any InstantiationAwareBeanPostProcessors have been registered */ - private boolean hasInstantiationAwareBeanPostProcessors; + private volatile boolean hasInstantiationAwareBeanPostProcessors; /** Indicates whether any DestructionAwareBeanPostProcessors have been registered */ - private boolean hasDestructionAwareBeanPostProcessors; + private volatile boolean hasDestructionAwareBeanPostProcessors; /** Map from scope identifier String to corresponding Scope */ private final Map scopes = new LinkedHashMap(8); @@ -845,14 +845,17 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp @Override public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) { Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null"); + // Remove from old position, if any this.beanPostProcessors.remove(beanPostProcessor); - this.beanPostProcessors.add(beanPostProcessor); + // Track whether it is instantiation/destruction aware if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) { this.hasInstantiationAwareBeanPostProcessors = true; } if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) { this.hasDestructionAwareBeanPostProcessors = true; } + // Add to end of list + this.beanPostProcessors.add(beanPostProcessor); } @Override @@ -982,7 +985,6 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp @Override public BeanDefinition getMergedBeanDefinition(String name) throws BeansException { String beanName = transformedBeanName(name); - // Efficiently check whether bean definition exists in this factory. if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) { return ((ConfigurableBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(beanName); @@ -994,7 +996,6 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp @Override public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException { String beanName = transformedBeanName(name); - Object beanInstance = getSingleton(beanName, false); if (beanInstance != null) { return (beanInstance instanceof FactoryBean); @@ -1003,13 +1004,11 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp // null instance registered return false; } - // No singleton instance found -> check bean definition. if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) { // No bean definition found in this factory -> delegate to parent. return ((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name); } - return isFactoryBean(beanName, getMergedLocalBeanDefinition(beanName)); }