diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java index 72b243aa819..4d34639919e 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java @@ -285,6 +285,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac // Use prototype bean definition, to avoid registering bean as dependent bean. RootBeanDefinition bd = new RootBeanDefinition(beanClass); bd.setScope(SCOPE_PROTOTYPE); + bd.allowCaching = false; return (T) createBean(beanClass.getName(), bd, null); } @@ -292,6 +293,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac // Use non-singleton bean definition, to avoid registering bean as dependent bean. RootBeanDefinition bd = new RootBeanDefinition(ClassUtils.getUserClass(existingBean)); bd.setScope(BeanDefinition.SCOPE_PROTOTYPE); + bd.allowCaching = false; BeanWrapper bw = new BeanWrapperImpl(existingBean); initBeanWrapper(bw); populateBean(bd.getBeanClass().getName(), bd, bw); @@ -310,6 +312,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac if (bd == null) { bd = new RootBeanDefinition(mbd); bd.setScope(BeanDefinition.SCOPE_PROTOTYPE); + bd.allowCaching = false; } BeanWrapper bw = new BeanWrapperImpl(existingBean); initBeanWrapper(bw); @@ -1053,7 +1056,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac * @param mbd the bean definition for the bean * @param bw BeanWrapper with bean instance */ - protected void populateBean(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw) { + protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) { PropertyValues pvs = mbd.getPropertyValues(); if (bw == null) { @@ -1109,7 +1112,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE); if (hasInstAwareBpps || needsDepCheck) { - PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw); + PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); if (hasInstAwareBpps) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { @@ -1237,34 +1240,51 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac /** * Extract a filtered set of PropertyDescriptors from the given BeanWrapper, - * excluding ignored dependency types or properties defined on ignored - * dependency interfaces. + * excluding ignored dependency types or properties defined on ignored dependency interfaces. * @param bw the BeanWrapper the bean was created with + * @param cache whether to cache filtered PropertyDescriptors for the given bean Class * @return the filtered PropertyDescriptors * @see #isExcludedFromDependencyCheck + * @see #filterPropertyDescriptorsForDependencyCheck(org.springframework.beans.BeanWrapper) */ - protected PropertyDescriptor[] filterPropertyDescriptorsForDependencyCheck(BeanWrapper bw) { + protected PropertyDescriptor[] filterPropertyDescriptorsForDependencyCheck(BeanWrapper bw, boolean cache) { PropertyDescriptor[] filtered = this.filteredPropertyDescriptorsCache.get(bw.getWrappedClass()); if (filtered == null) { - synchronized (this.filteredPropertyDescriptorsCache) { - filtered = this.filteredPropertyDescriptorsCache.get(bw.getWrappedClass()); - if (filtered == null) { - List pds = - new LinkedList(Arrays.asList(bw.getPropertyDescriptors())); - for (Iterator it = pds.iterator(); it.hasNext();) { - PropertyDescriptor pd = it.next(); - if (isExcludedFromDependencyCheck(pd)) { - it.remove(); - } + if (cache) { + synchronized (this.filteredPropertyDescriptorsCache) { + filtered = this.filteredPropertyDescriptorsCache.get(bw.getWrappedClass()); + if (filtered == null) { + filtered = filterPropertyDescriptorsForDependencyCheck(bw); + this.filteredPropertyDescriptorsCache.put(bw.getWrappedClass(), filtered); } - filtered = pds.toArray(new PropertyDescriptor[pds.size()]); - this.filteredPropertyDescriptorsCache.put(bw.getWrappedClass(), filtered); } } + else { + filtered = filterPropertyDescriptorsForDependencyCheck(bw); + } } return filtered; } + /** + * Extract a filtered set of PropertyDescriptors from the given BeanWrapper, + * excluding ignored dependency types or properties defined on ignored dependency interfaces. + * @param bw the BeanWrapper the bean was created with + * @return the filtered PropertyDescriptors + * @see #isExcludedFromDependencyCheck + */ + protected PropertyDescriptor[] filterPropertyDescriptorsForDependencyCheck(BeanWrapper bw) { + List pds = + new LinkedList(Arrays.asList(bw.getPropertyDescriptors())); + for (Iterator it = pds.iterator(); it.hasNext();) { + PropertyDescriptor pd = it.next(); + if (isExcludedFromDependencyCheck(pd)) { + it.remove(); + } + } + return pds.toArray(new PropertyDescriptor[pds.size()]); + } + /** * Determine whether the given bean property is excluded from dependency checks. *

This implementation excludes properties defined by CGLIB and diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/RootBeanDefinition.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/RootBeanDefinition.java index 8d816a2b208..808b4f57159 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/RootBeanDefinition.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/RootBeanDefinition.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. @@ -56,7 +56,9 @@ public class RootBeanDefinition extends AbstractBeanDefinition { private BeanDefinitionHolder decoratedDefinition; - boolean isFactoryMethodUnique; + boolean allowCaching = true; + + boolean isFactoryMethodUnique = false; /** Package-visible field for caching the resolved constructor or factory method */ Object resolvedConstructorOrFactoryMethod;