summaryrefslogtreecommitdiff
path: root/spring-beans/src/main/java/org/springframework/beans/factory/support
diff options
context:
space:
mode:
authorEmmanuel Bourg <ebourg@apache.org>2015-07-15 23:21:27 +0200
committerEmmanuel Bourg <ebourg@apache.org>2015-07-15 23:21:27 +0200
commitda46d30e80e4c59a41cf52055d06faa1dbb7e383 (patch)
tree52b707fbbccd5b6100088913f32c1cbd00568790 /spring-beans/src/main/java/org/springframework/beans/factory/support
parentc03c348db4e91c613982cbe6c99d0cf04ea14fe3 (diff)
Imported Upstream version 4.0.9
Diffstat (limited to 'spring-beans/src/main/java/org/springframework/beans/factory/support')
-rw-r--r--spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java86
-rw-r--r--spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanDefinition.java77
-rw-r--r--spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanDefinitionReader.java8
-rw-r--r--spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java64
-rw-r--r--spring-beans/src/main/java/org/springframework/beans/factory/support/AutowireCandidateQualifier.java4
-rw-r--r--spring-beans/src/main/java/org/springframework/beans/factory/support/AutowireCandidateResolver.java15
-rw-r--r--spring-beans/src/main/java/org/springframework/beans/factory/support/AutowireUtils.java3
-rw-r--r--spring-beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionBuilder.java53
-rw-r--r--spring-beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionResource.java2
-rw-r--r--spring-beans/src/main/java/org/springframework/beans/factory/support/CglibSubclassingInstantiationStrategy.java215
-rw-r--r--spring-beans/src/main/java/org/springframework/beans/factory/support/ChildBeanDefinition.java5
-rw-r--r--spring-beans/src/main/java/org/springframework/beans/factory/support/ConstructorResolver.java14
-rw-r--r--spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultBeanNameGenerator.java3
-rw-r--r--spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java171
-rw-r--r--spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultSingletonBeanRegistry.java76
-rw-r--r--spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java22
-rw-r--r--spring-beans/src/main/java/org/springframework/beans/factory/support/FactoryBeanRegistrySupport.java2
-rw-r--r--spring-beans/src/main/java/org/springframework/beans/factory/support/GenericBeanDefinition.java2
-rw-r--r--spring-beans/src/main/java/org/springframework/beans/factory/support/GenericTypeAwareAutowireCandidateResolver.java170
-rw-r--r--spring-beans/src/main/java/org/springframework/beans/factory/support/LookupOverride.java2
-rw-r--r--spring-beans/src/main/java/org/springframework/beans/factory/support/ManagedArray.java2
-rw-r--r--spring-beans/src/main/java/org/springframework/beans/factory/support/ManagedList.java5
-rw-r--r--spring-beans/src/main/java/org/springframework/beans/factory/support/ManagedMap.java5
-rw-r--r--spring-beans/src/main/java/org/springframework/beans/factory/support/ManagedProperties.java3
-rw-r--r--spring-beans/src/main/java/org/springframework/beans/factory/support/ManagedSet.java5
-rw-r--r--spring-beans/src/main/java/org/springframework/beans/factory/support/MethodOverride.java1
-rw-r--r--spring-beans/src/main/java/org/springframework/beans/factory/support/PropertiesBeanDefinitionReader.java15
-rw-r--r--spring-beans/src/main/java/org/springframework/beans/factory/support/ReplaceOverride.java3
-rw-r--r--spring-beans/src/main/java/org/springframework/beans/factory/support/RootBeanDefinition.java62
-rw-r--r--spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleAutowireCandidateResolver.java10
-rw-r--r--spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleBeanDefinitionRegistry.java7
-rw-r--r--spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleInstantiationStrategy.java8
-rw-r--r--spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleSecurityContextProvider.java1
-rw-r--r--spring-beans/src/main/java/org/springframework/beans/factory/support/StaticListableBeanFactory.java34
34 files changed, 811 insertions, 344 deletions
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 f1bbf032..b0525263 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
@@ -68,8 +68,8 @@ import org.springframework.beans.factory.config.DependencyDescriptor;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor;
import org.springframework.beans.factory.config.TypedStringValue;
+import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.core.GenericTypeResolver;
-import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.core.MethodParameter;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.core.PriorityOrdered;
@@ -120,7 +120,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();
/** Resolver strategy for method parameter names */
- private ParameterNameDiscoverer parameterNameDiscoverer = new LocalVariableTableParameterNameDiscoverer();
+ private ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
/** Whether to automatically try to resolve circular references between beans */
private boolean allowCircularReferences = true;
@@ -191,7 +191,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
/**
* Set the ParameterNameDiscoverer to use for resolving method parameter
* names if needed (e.g. for constructor names).
- * <p>The default is {@link LocalVariableTableParameterNameDiscoverer}.
+ * <p>Default is a {@link DefaultParameterNameDiscoverer}.
*/
public void setParameterNameDiscoverer(ParameterNameDiscoverer parameterNameDiscoverer) {
this.parameterNameDiscoverer = parameterNameDiscoverer;
@@ -280,6 +280,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
// Typical methods for creating and populating external bean instances
//-------------------------------------------------------------------------
+ @Override
@SuppressWarnings("unchecked")
public <T> T createBean(Class<T> beanClass) throws BeansException {
// Use prototype bean definition, to avoid registering bean as dependent bean.
@@ -289,6 +290,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
return (T) createBean(beanClass.getName(), bd, null);
}
+ @Override
public void autowireBean(Object existingBean) {
// Use non-singleton bean definition, to avoid registering bean as dependent bean.
RootBeanDefinition bd = new RootBeanDefinition(ClassUtils.getUserClass(existingBean));
@@ -299,6 +301,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
populateBean(bd.getBeanClass().getName(), bd, bw);
}
+ @Override
public Object configureBean(Object existingBean, String beanName) throws BeansException {
markBeanAsCreated(beanName);
BeanDefinition mbd = getMergedBeanDefinition(beanName);
@@ -320,6 +323,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
return initializeBean(beanName, existingBean, bd);
}
+ @Override
public Object resolveDependency(DependencyDescriptor descriptor, String beanName) throws BeansException {
return resolveDependency(descriptor, beanName, null, null);
}
@@ -329,6 +333,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
// Specialized methods for fine-grained control over the bean lifecycle
//-------------------------------------------------------------------------
+ @Override
public Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException {
// Use non-singleton bean definition, to avoid registering bean as dependent bean.
RootBeanDefinition bd = new RootBeanDefinition(beanClass, autowireMode, dependencyCheck);
@@ -336,6 +341,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
return createBean(beanClass.getName(), bd, null);
}
+ @Override
public Object autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException {
// Use non-singleton bean definition, to avoid registering bean as dependent bean.
final RootBeanDefinition bd = new RootBeanDefinition(beanClass, autowireMode, dependencyCheck);
@@ -348,6 +354,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
final BeanFactory parent = this;
if (System.getSecurityManager() != null) {
bean = AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ @Override
public Object run() {
return getInstantiationStrategy().instantiate(bd, null, parent);
}
@@ -361,6 +368,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
}
}
+ @Override
public void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck)
throws BeansException {
@@ -376,6 +384,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
populateBean(bd.getBeanClass().getName(), bd, bw);
}
+ @Override
public void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException {
markBeanAsCreated(beanName);
BeanDefinition bd = getMergedBeanDefinition(beanName);
@@ -384,10 +393,12 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
applyPropertyValues(beanName, bd, bw, bd.getPropertyValues());
}
+ @Override
public Object initializeBean(Object existingBean, String beanName) {
return initializeBean(beanName, existingBean, null);
}
+ @Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
@@ -401,6 +412,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
return result;
}
+ @Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
@@ -414,6 +426,11 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
return result;
}
+ @Override
+ public void destroyBean(Object existingBean) {
+ new DisposableBeanAdapter(existingBean, getBeanPostProcessors(), getAccessControlContext()).destroy();
+ }
+
//---------------------------------------------------------------------
// Implementation of relevant AbstractBeanFactory template methods
@@ -507,6 +524,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, new ObjectFactory<Object>() {
+ @Override
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
@@ -609,7 +627,12 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
* @return the type for the bean if determinable, or {@code null} else
* @see #createBean
*/
- protected Class<?> getTypeForFactoryMethod(String beanName, RootBeanDefinition mbd, Class[] typesToMatch) {
+ protected Class<?> getTypeForFactoryMethod(String beanName, RootBeanDefinition mbd, Class<?>... typesToMatch) {
+ Class<?> preResolved = mbd.resolvedFactoryMethodReturnType;
+ if (preResolved != null) {
+ return preResolved;
+ }
+
Class<?> factoryClass;
boolean isStatic = true;
@@ -635,6 +658,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
// If all factory methods have the same return type, return that type.
// Can't clearly figure out exact method due to type converting / autowiring!
Class<?> commonType = null;
+ boolean cache = false;
int minNrOfArgs = mbd.getConstructorArgumentValues().getArgumentCount();
Method[] candidates = ReflectionUtils.getUniqueDeclaredMethods(factoryClass);
for (Method factoryMethod : candidates) {
@@ -669,6 +693,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
Class<?> returnType = AutowireUtils.resolveReturnTypeForFactoryMethod(
factoryMethod, args, getBeanClassLoader());
if (returnType != null) {
+ cache = true;
commonType = ClassUtils.determineCommonAncestor(returnType, commonType);
}
}
@@ -686,6 +711,9 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
if (commonType != null) {
// Clear return type found: all factory methods return same type.
+ if (cache) {
+ mbd.resolvedFactoryMethodReturnType = commonType;
+ }
return commonType;
}
else {
@@ -712,27 +740,36 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
String factoryBeanName = mbd.getFactoryBeanName();
final String factoryMethodName = mbd.getFactoryMethodName();
- if (factoryBeanName != null && factoryMethodName != null) {
- // Try to obtain the FactoryBean's object type without instantiating it at all.
- BeanDefinition fbDef = getBeanDefinition(factoryBeanName);
- if (fbDef instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) fbDef).hasBeanClass()) {
- // CGLIB subclass methods hide generic parameters; look at the original user class.
- Class<?> fbClass = ClassUtils.getUserClass(((AbstractBeanDefinition) fbDef).getBeanClass());
- // Find the given factory method, taking into account that in the case of
- // @Bean methods, there may be parameters present.
- ReflectionUtils.doWithMethods(fbClass,
- new ReflectionUtils.MethodCallback() {
- public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
- if (method.getName().equals(factoryMethodName) &&
- FactoryBean.class.isAssignableFrom(method.getReturnType())) {
- objectType.value = GenericTypeResolver.resolveReturnTypeArgument(method, FactoryBean.class);
+ if (factoryBeanName != null) {
+ if (factoryMethodName != null) {
+ // Try to obtain the FactoryBean's object type without instantiating it at all.
+ BeanDefinition fbDef = getBeanDefinition(factoryBeanName);
+ if (fbDef instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) fbDef).hasBeanClass()) {
+ // CGLIB subclass methods hide generic parameters; look at the original user class.
+ Class<?> fbClass = ClassUtils.getUserClass(((AbstractBeanDefinition) fbDef).getBeanClass());
+ // Find the given factory method, taking into account that in the case of
+ // @Bean methods, there may be parameters present.
+ ReflectionUtils.doWithMethods(fbClass,
+ new ReflectionUtils.MethodCallback() {
+ @Override
+ public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
+ if (method.getName().equals(factoryMethodName) &&
+ FactoryBean.class.isAssignableFrom(method.getReturnType())) {
+ objectType.value = GenericTypeResolver.resolveReturnTypeArgument(method, FactoryBean.class);
+ }
}
- }
- });
- if (objectType.value != null) {
- return objectType.value;
+ });
+ if (objectType.value != null) {
+ return objectType.value;
+ }
}
}
+ // If not resolvable above and the referenced factory bean doesn't exist yet,
+ // exit here - we don't want to force the creation of another bean just to
+ // obtain a FactoryBean's object type...
+ if (!isBeanEligibleForMetadataCaching(factoryBeanName)) {
+ return null;
+ }
}
FactoryBean<?> fb = (mbd.isSingleton() ?
@@ -1023,6 +1060,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
final BeanFactory parent = this;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ @Override
public Object run() {
return getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
@@ -1492,6 +1530,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ @Override
public Object run() {
invokeAwareMethods(beanName, bean);
return null;
@@ -1559,6 +1598,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
+ @Override
public Object run() throws Exception {
((InitializingBean) bean).afterPropertiesSet();
return null;
@@ -1616,6 +1656,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
+ @Override
public Object run() throws Exception {
ReflectionUtils.makeAccessible(initMethod);
return null;
@@ -1623,6 +1664,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
});
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
+ @Override
public Object run() throws Exception {
initMethod.invoke(bean);
return null;
diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanDefinition.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanDefinition.java
index 5094ad71..050c9d1d 100644
--- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanDefinition.java
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanDefinition.java
@@ -139,10 +139,6 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
private String scope = SCOPE_DEFAULT;
- private boolean singleton = true;
-
- private boolean prototype = false;
-
private boolean abstractFlag = false;
private boolean lazyInit = false;
@@ -211,17 +207,6 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
* Create a new AbstractBeanDefinition as a deep copy of the given
* bean definition.
* @param original the original bean definition to copy from
- * @deprecated since Spring 2.5, in favor of {@link #AbstractBeanDefinition(BeanDefinition)}
- */
- @Deprecated
- protected AbstractBeanDefinition(AbstractBeanDefinition original) {
- this((BeanDefinition) original);
- }
-
- /**
- * Create a new AbstractBeanDefinition as a deep copy of the given
- * bean definition.
- * @param original the original bean definition to copy from
*/
protected AbstractBeanDefinition(BeanDefinition original) {
setParentName(original.getParentName());
@@ -268,17 +253,6 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
* Override settings in this bean definition (presumably a copied parent
* from a parent-child inheritance relationship) from the given bean
* definition (presumably the child).
- * @deprecated since Spring 2.5, in favor of {@link #overrideFrom(BeanDefinition)}
- */
- @Deprecated
- public void overrideFrom(AbstractBeanDefinition other) {
- overrideFrom((BeanDefinition) other);
- }
-
- /**
- * Override settings in this bean definition (presumably a copied parent
- * from a parent-child inheritance relationship) from the given bean
- * definition (presumably the child).
* <ul>
* <li>Will override beanClass if specified in the given bean definition.
* <li>Will always take {@code abstract}, {@code scope},
@@ -389,10 +363,12 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
return (Class<?>) beanClassObject;
}
+ @Override
public void setBeanClassName(String beanClassName) {
this.beanClass = beanClassName;
}
+ @Override
public String getBeanClassName() {
Object beanClassObject = this.beanClass;
if (beanClassObject instanceof Class) {
@@ -432,46 +408,27 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
* @see #SCOPE_SINGLETON
* @see #SCOPE_PROTOTYPE
*/
+ @Override
public void setScope(String scope) {
this.scope = scope;
- this.singleton = SCOPE_SINGLETON.equals(scope) || SCOPE_DEFAULT.equals(scope);
- this.prototype = SCOPE_PROTOTYPE.equals(scope);
}
/**
* Return the name of the target scope for the bean.
*/
+ @Override
public String getScope() {
return this.scope;
}
/**
- * Set if this a <b>Singleton</b>, with a single, shared instance returned
- * on all calls. In case of "false", the BeanFactory will apply the <b>Prototype</b>
- * design pattern, with each caller requesting an instance getting an independent
- * instance. How this is exactly defined will depend on the BeanFactory.
- * <p>"Singletons" are the commoner type, so the default is "true".
- * Note that as of Spring 2.0, this flag is just an alternative way to
- * specify scope="singleton" or scope="prototype".
- * @deprecated since Spring 2.5, in favor of {@link #setScope}
- * @see #setScope
- * @see #SCOPE_SINGLETON
- * @see #SCOPE_PROTOTYPE
- */
- @Deprecated
- public void setSingleton(boolean singleton) {
- this.scope = (singleton ? SCOPE_SINGLETON : SCOPE_PROTOTYPE);
- this.singleton = singleton;
- this.prototype = !singleton;
- }
-
- /**
* Return whether this a <b>Singleton</b>, with a single shared instance
* returned from all calls.
* @see #SCOPE_SINGLETON
*/
+ @Override
public boolean isSingleton() {
- return this.singleton;
+ return SCOPE_SINGLETON.equals(scope) || SCOPE_DEFAULT.equals(scope);
}
/**
@@ -479,8 +436,9 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
* returned for each call.
* @see #SCOPE_PROTOTYPE
*/
+ @Override
public boolean isPrototype() {
- return this.prototype;
+ return SCOPE_PROTOTYPE.equals(scope);
}
/**
@@ -497,6 +455,7 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
* Return whether this bean is "abstract", i.e. not meant to be instantiated
* itself but rather just serving as parent for concrete child bean definitions.
*/
+ @Override
public boolean isAbstract() {
return this.abstractFlag;
}
@@ -506,6 +465,7 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
* <p>If {@code false}, the bean will get instantiated on startup by bean
* factories that perform eager initialization of singletons.
*/
+ @Override
public void setLazyInit(boolean lazyInit) {
this.lazyInit = lazyInit;
}
@@ -514,6 +474,7 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
* Return whether this bean should be lazily initialized, i.e. not
* eagerly instantiated on startup. Only applicable to a singleton bean.
*/
+ @Override
public boolean isLazyInit() {
return this.lazyInit;
}
@@ -594,6 +555,7 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
* constructor arguments. This property should just be necessary for other kinds
* of dependencies like statics (*ugh*) or database preparation on startup.
*/
+ @Override
public void setDependsOn(String[] dependsOn) {
this.dependsOn = dependsOn;
}
@@ -601,6 +563,7 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
/**
* Return the bean names that this bean depends on.
*/
+ @Override
public String[] getDependsOn() {
return this.dependsOn;
}
@@ -608,6 +571,7 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
/**
* Set whether this bean is a candidate for getting autowired into some other bean.
*/
+ @Override
public void setAutowireCandidate(boolean autowireCandidate) {
this.autowireCandidate = autowireCandidate;
}
@@ -615,6 +579,7 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
/**
* Return whether this bean is a candidate for getting autowired into some other bean.
*/
+ @Override
public boolean isAutowireCandidate() {
return this.autowireCandidate;
}
@@ -624,6 +589,7 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
* If this value is true for exactly one bean among multiple
* matching candidates, it will serve as a tie-breaker.
*/
+ @Override
public void setPrimary(boolean primary) {
this.primary = primary;
}
@@ -633,6 +599,7 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
* If this value is true for exactly one bean among multiple
* matching candidates, it will serve as a tie-breaker.
*/
+ @Override
public boolean isPrimary() {
return this.primary;
}
@@ -728,6 +695,7 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
/**
* Return constructor argument values for this bean (never {@code null}).
*/
+ @Override
public ConstructorArgumentValues getConstructorArgumentValues() {
return this.constructorArgumentValues;
}
@@ -749,6 +717,7 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
/**
* Return property values for this bean (never {@code null}).
*/
+ @Override
public MutablePropertyValues getPropertyValues() {
return this.propertyValues;
}
@@ -770,18 +739,22 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
}
+ @Override
public void setFactoryBeanName(String factoryBeanName) {
this.factoryBeanName = factoryBeanName;
}
+ @Override
public String getFactoryBeanName() {
return this.factoryBeanName;
}
+ @Override
public void setFactoryMethodName(String factoryMethodName) {
this.factoryMethodName = factoryMethodName;
}
+ @Override
public String getFactoryMethodName() {
return this.factoryMethodName;
}
@@ -878,6 +851,7 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
/**
* Return the role hint for this {@code BeanDefinition}.
*/
+ @Override
public int getRole() {
return this.role;
}
@@ -890,6 +864,7 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
this.description = description;
}
+ @Override
public String getDescription() {
return this.description;
}
@@ -917,6 +892,7 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
this.resource = new DescriptiveResource(resourceDescription);
}
+ @Override
public String getResourceDescription() {
return (this.resource != null ? this.resource.getDescription() : null);
}
@@ -928,6 +904,7 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
this.resource = new BeanDefinitionResource(originatingBd);
}
+ @Override
public BeanDefinition getOriginatingBeanDefinition() {
return (this.resource instanceof BeanDefinitionResource ?
((BeanDefinitionResource) this.resource).getBeanDefinition() : null);
diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanDefinitionReader.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanDefinitionReader.java
index 32db844c..9a267cce 100644
--- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanDefinitionReader.java
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanDefinitionReader.java
@@ -102,6 +102,7 @@ public abstract class AbstractBeanDefinitionReader implements EnvironmentCapable
return this.registry;
}
+ @Override
public final BeanDefinitionRegistry getRegistry() {
return this.registry;
}
@@ -121,6 +122,7 @@ public abstract class AbstractBeanDefinitionReader implements EnvironmentCapable
this.resourceLoader = resourceLoader;
}
+ @Override
public ResourceLoader getResourceLoader() {
return this.resourceLoader;
}
@@ -136,6 +138,7 @@ public abstract class AbstractBeanDefinitionReader implements EnvironmentCapable
this.beanClassLoader = beanClassLoader;
}
+ @Override
public ClassLoader getBeanClassLoader() {
return this.beanClassLoader;
}
@@ -149,6 +152,7 @@ public abstract class AbstractBeanDefinitionReader implements EnvironmentCapable
this.environment = environment;
}
+ @Override
public Environment getEnvironment() {
return this.environment;
}
@@ -162,11 +166,13 @@ public abstract class AbstractBeanDefinitionReader implements EnvironmentCapable
this.beanNameGenerator = (beanNameGenerator != null ? beanNameGenerator : new DefaultBeanNameGenerator());
}
+ @Override
public BeanNameGenerator getBeanNameGenerator() {
return this.beanNameGenerator;
}
+ @Override
public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
Assert.notNull(resources, "Resource array must not be null");
int counter = 0;
@@ -176,6 +182,7 @@ public abstract class AbstractBeanDefinitionReader implements EnvironmentCapable
return counter;
}
+ @Override
public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException {
return loadBeanDefinitions(location, null);
}
@@ -236,6 +243,7 @@ public abstract class AbstractBeanDefinitionReader implements EnvironmentCapable
}
}
+ @Override
public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
Assert.notNull(locations, "Location array must not be null");
int counter = 0;
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 77926309..d0a8f18a 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
@@ -24,6 +24,7 @@ import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
@@ -160,7 +161,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
new ConcurrentHashMap<String, RootBeanDefinition>(64);
/** Names of beans that have already been created at least once */
- private final Map<String, Boolean> alreadyCreated = new ConcurrentHashMap<String, Boolean>(64);
+ private final Set<String> alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>(64));
/** Names of beans that are currently in creation */
private final ThreadLocal<Object> prototypesCurrentlyInCreation =
@@ -187,14 +188,17 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
// Implementation of BeanFactory interface
//---------------------------------------------------------------------
+ @Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
+ @Override
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
return doGetBean(name, requiredType, null, false);
}
+ @Override
public Object getBean(String name, Object... args) throws BeansException {
return doGetBean(name, null, args, false);
}
@@ -280,14 +284,19 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dependsOnBean : dependsOn) {
- getBean(dependsOnBean);
+ if (isDependent(beanName, dependsOnBean)) {
+ throw new BeanCreationException(mbd.getResourceDescription(), beanName,
+ "Circular depends-on relationship between '" + beanName + "' and '" + dependsOnBean + "'");
+ }
registerDependentBean(dependsOnBean, beanName);
+ getBean(dependsOnBean);
}
}
// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
+ @Override
public Object getObject() throws BeansException {
try {
return createBean(beanName, mbd, args);
@@ -325,6 +334,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
}
try {
Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
+ @Override
public Object getObject() throws BeansException {
beforePrototypeCreation(beanName);
try {
@@ -367,6 +377,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
return (T) bean;
}
+ @Override
public boolean containsBean(String name) {
String beanName = transformedBeanName(name);
if (containsSingleton(beanName) || containsBeanDefinition(beanName)) {
@@ -377,6 +388,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
return (parentBeanFactory != null && parentBeanFactory.containsBean(originalBeanName(name)));
}
+ @Override
public boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
String beanName = transformedBeanName(name);
@@ -422,6 +434,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
}
}
+ @Override
public boolean isPrototype(String name) throws NoSuchBeanDefinitionException {
String beanName = transformedBeanName(name);
@@ -446,6 +459,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
final FactoryBean<?> factoryBean = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
if (System.getSecurityManager() != null) {
return AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
+ @Override
public Boolean run() {
return ((factoryBean instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factoryBean).isPrototype()) ||
!factoryBean.isSingleton());
@@ -463,6 +477,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
}
}
+ @Override
public boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException {
String beanName = transformedBeanName(name);
Class<?> typeToMatch = (targetType != null ? targetType : Object.class);
@@ -543,6 +558,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
}
}
+ @Override
public Class<?> getType(String name) throws NoSuchBeanDefinitionException {
String beanName = transformedBeanName(name);
@@ -633,10 +649,12 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
// Implementation of HierarchicalBeanFactory interface
//---------------------------------------------------------------------
+ @Override
public BeanFactory getParentBeanFactory() {
return this.parentBeanFactory;
}
+ @Override
public boolean containsLocalBean(String name) {
String beanName = transformedBeanName(name);
return ((containsSingleton(beanName) || containsBeanDefinition(beanName)) &&
@@ -648,6 +666,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
// Implementation of ConfigurableBeanFactory interface
//---------------------------------------------------------------------
+ @Override
public void setParentBeanFactory(BeanFactory parentBeanFactory) {
if (this.parentBeanFactory != null && this.parentBeanFactory != parentBeanFactory) {
throw new IllegalStateException("Already associated with parent BeanFactory: " + this.parentBeanFactory);
@@ -655,46 +674,57 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
this.parentBeanFactory = parentBeanFactory;
}
+ @Override
public void setBeanClassLoader(ClassLoader beanClassLoader) {
this.beanClassLoader = (beanClassLoader != null ? beanClassLoader : ClassUtils.getDefaultClassLoader());
}
+ @Override
public ClassLoader getBeanClassLoader() {
return this.beanClassLoader;
}
+ @Override
public void setTempClassLoader(ClassLoader tempClassLoader) {
this.tempClassLoader = tempClassLoader;
}
+ @Override
public ClassLoader getTempClassLoader() {
return this.tempClassLoader;
}
+ @Override
public void setCacheBeanMetadata(boolean cacheBeanMetadata) {
this.cacheBeanMetadata = cacheBeanMetadata;
}
+ @Override
public boolean isCacheBeanMetadata() {
return this.cacheBeanMetadata;
}
+ @Override
public void setBeanExpressionResolver(BeanExpressionResolver resolver) {
this.beanExpressionResolver = resolver;
}
+ @Override
public BeanExpressionResolver getBeanExpressionResolver() {
return this.beanExpressionResolver;
}
+ @Override
public void setConversionService(ConversionService conversionService) {
this.conversionService = conversionService;
}
+ @Override
public ConversionService getConversionService() {
return this.conversionService;
}
+ @Override
public void addPropertyEditorRegistrar(PropertyEditorRegistrar registrar) {
Assert.notNull(registrar, "PropertyEditorRegistrar must not be null");
this.propertyEditorRegistrars.add(registrar);
@@ -707,12 +737,14 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
return this.propertyEditorRegistrars;
}
+ @Override
public void registerCustomEditor(Class<?> requiredType, Class<? extends PropertyEditor> propertyEditorClass) {
Assert.notNull(requiredType, "Required type must not be null");
Assert.isAssignable(PropertyEditor.class, propertyEditorClass);
this.customEditors.put(requiredType, propertyEditorClass);
}
+ @Override
public void copyRegisteredEditorsTo(PropertyEditorRegistry registry) {
registerCustomEditors(registry);
}
@@ -724,6 +756,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
return this.customEditors;
}
+ @Override
public void setTypeConverter(TypeConverter typeConverter) {
this.typeConverter = typeConverter;
}
@@ -736,6 +769,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
return this.typeConverter;
}
+ @Override
public TypeConverter getTypeConverter() {
TypeConverter customConverter = getCustomTypeConverter();
if (customConverter != null) {
@@ -750,11 +784,13 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
}
}
+ @Override
public void addEmbeddedValueResolver(StringValueResolver valueResolver) {
Assert.notNull(valueResolver, "StringValueResolver must not be null");
this.embeddedValueResolvers.add(valueResolver);
}
+ @Override
public String resolveEmbeddedValue(String value) {
String result = value;
for (StringValueResolver resolver : this.embeddedValueResolvers) {
@@ -766,6 +802,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
return result;
}
+ @Override
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
this.beanPostProcessors.remove(beanPostProcessor);
@@ -778,6 +815,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
}
}
+ @Override
public int getBeanPostProcessorCount() {
return this.beanPostProcessors.size();
}
@@ -810,6 +848,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
return this.hasDestructionAwareBeanPostProcessors;
}
+ @Override
public void registerScope(String scopeName, Scope scope) {
Assert.notNull(scopeName, "Scope identifier must not be null");
Assert.notNull(scope, "Scope must not be null");
@@ -819,10 +858,12 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
this.scopes.put(scopeName, scope);
}
+ @Override
public String[] getRegisteredScopeNames() {
return StringUtils.toStringArray(this.scopes.keySet());
}
+ @Override
public Scope getRegisteredScope(String scopeName) {
Assert.notNull(scopeName, "Scope identifier must not be null");
return this.scopes.get(scopeName);
@@ -848,6 +889,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
AccessController.getContext());
}
+ @Override
public void copyConfigurationFrom(ConfigurableBeanFactory otherFactory) {
Assert.notNull(otherFactory, "BeanFactory must not be null");
setBeanClassLoader(otherFactory.getBeanClassLoader());
@@ -881,6 +923,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
* @throws NoSuchBeanDefinitionException if there is no bean with the given name
* @throws BeanDefinitionStoreException in case of an invalid bean definition
*/
+ @Override
public BeanDefinition getMergedBeanDefinition(String name) throws BeansException {
String beanName = transformedBeanName(name);
@@ -892,6 +935,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
return getMergedLocalBeanDefinition(beanName);
}
+ @Override
public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException {
String beanName = transformedBeanName(name);
@@ -915,7 +959,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
@Override
public boolean isActuallyInCreation(String beanName) {
- return isSingletonCurrentlyInCreation(beanName) || isPrototypeCurrentlyInCreation(beanName);
+ return (isSingletonCurrentlyInCreation(beanName) || isPrototypeCurrentlyInCreation(beanName));
}
/**
@@ -974,6 +1018,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
}
}
+ @Override
public void destroyBean(String beanName, Object beanInstance) {
destroyBean(beanName, beanInstance, getMergedLocalBeanDefinition(beanName));
}
@@ -989,6 +1034,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
new DisposableBeanAdapter(beanInstance, beanName, mbd, getBeanPostProcessors(), getAccessControlContext()).destroy();
}
+ @Override
public void destroyScopedBean(String beanName) {
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
if (mbd.isSingleton() || mbd.isPrototype()) {
@@ -1261,6 +1307,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
}
if (System.getSecurityManager() != null) {
return AccessController.doPrivileged(new PrivilegedExceptionAction<Class<?>>() {
+ @Override
public Class<?> run() throws Exception {
return doResolveBeanClass(mbd, typesToMatch);
}
@@ -1388,8 +1435,8 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
* @param beanName the name of the bean
*/
protected void markBeanAsCreated(String beanName) {
- if (!this.alreadyCreated.containsKey(beanName)) {
- this.alreadyCreated.put(beanName, Boolean.TRUE);
+ if (!this.alreadyCreated.contains(beanName)) {
+ this.alreadyCreated.add(beanName);
}
}
@@ -1409,7 +1456,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
* at this point already
*/
protected boolean isBeanEligibleForMetadataCaching(String beanName) {
- return this.alreadyCreated.containsKey(beanName);
+ return this.alreadyCreated.contains(beanName);
}
/**
@@ -1419,7 +1466,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
* @return {@code true} if actually removed, {@code false} otherwise
*/
protected boolean removeSingletonIfCreatedForTypeCheckOnly(String beanName) {
- if (!this.alreadyCreated.containsKey(beanName)) {
+ if (!this.alreadyCreated.contains(beanName)) {
removeSingleton(beanName);
return true;
}
@@ -1580,8 +1627,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
* instantiation within this class is performed by this method.
* @param beanName the name of the bean
* @param mbd the merged bean definition for the bean
- * @param args arguments to use if creating a prototype using explicit arguments to a
- * static factory method. This parameter must be {@code null} except in this case.
+ * @param args arguments to use if creating a prototype using explicit arguments
* @return a new instance of the bean
* @throws BeanCreationException if the bean could not be created
*/
diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AutowireCandidateQualifier.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AutowireCandidateQualifier.java
index 6846390e..f5991ac9 100644
--- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AutowireCandidateQualifier.java
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AutowireCandidateQualifier.java
@@ -42,7 +42,7 @@ public class AutowireCandidateQualifier extends BeanMetadataAttributeAccessor {
* given type.
* @param type the annotation type
*/
- public AutowireCandidateQualifier(Class type) {
+ public AutowireCandidateQualifier(Class<?> type) {
this(type.getName());
}
@@ -65,7 +65,7 @@ public class AutowireCandidateQualifier extends BeanMetadataAttributeAccessor {
* @param type the annotation type
* @param value the annotation value to match
*/
- public AutowireCandidateQualifier(Class type, Object value) {
+ public AutowireCandidateQualifier(Class<?> type, Object value) {
this(type.getName(), value);
}
diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AutowireCandidateResolver.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AutowireCandidateResolver.java
index cd2c41e1..2c3e15fc 100644
--- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AutowireCandidateResolver.java
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AutowireCandidateResolver.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2012 the original author or authors.
+ * Copyright 2002-2013 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.
@@ -23,8 +23,8 @@ import org.springframework.beans.factory.config.DependencyDescriptor;
* Strategy interface for determining whether a specific bean definition
* qualifies as an autowire candidate for a specific dependency.
*
- * @author Mark Fisher
* @author Juergen Hoeller
+ * @author Mark Fisher
* @since 2.5
*/
public interface AutowireCandidateResolver {
@@ -47,4 +47,15 @@ public interface AutowireCandidateResolver {
*/
Object getSuggestedValue(DependencyDescriptor descriptor);
+ /**
+ * Build a proxy for lazy resolution of the actual dependency target,
+ * if demanded by the injection point.
+ * @param descriptor the descriptor for the target method parameter or field
+ * @param beanName the name of the bean that contains the injection point
+ * @return the lazy resolution proxy for the actual dependency target,
+ * or {@code null} if straight resolution is to be performed
+ * @since 4.0
+ */
+ Object getLazyResolutionProxyIfNecessary(DependencyDescriptor descriptor, String beanName);
+
}
diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AutowireUtils.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AutowireUtils.java
index 1ef3ceaf..5111599f 100644
--- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AutowireUtils.java
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AutowireUtils.java
@@ -58,6 +58,7 @@ abstract class AutowireUtils {
*/
public static void sortConstructors(Constructor<?>[] constructors) {
Arrays.sort(constructors, new Comparator<Constructor<?>>() {
+ @Override
public int compare(Constructor<?> c1, Constructor<?> c2) {
boolean p1 = Modifier.isPublic(c1.getModifiers());
boolean p2 = Modifier.isPublic(c2.getModifiers());
@@ -80,6 +81,7 @@ abstract class AutowireUtils {
*/
public static void sortFactoryMethods(Method[] factoryMethods) {
Arrays.sort(factoryMethods, new Comparator<Method>() {
+ @Override
public int compare(Method fm1, Method fm2) {
boolean p1 = Modifier.isPublic(fm1.getModifiers());
boolean p2 = Modifier.isPublic(fm2.getModifiers());
@@ -287,6 +289,7 @@ abstract class AutowireUtils {
this.objectFactory = objectFactory;
}
+ @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String methodName = method.getName();
if (methodName.equals("equals")) {
diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionBuilder.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionBuilder.java
index 5b9b571f..f70e163c 100644
--- a/spring-beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionBuilder.java
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionBuilder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2012 the original author or authors.
+ * Copyright 2002-2013 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.
@@ -45,7 +45,7 @@ public class BeanDefinitionBuilder {
* Create a new {@code BeanDefinitionBuilder} used to construct a {@link GenericBeanDefinition}.
* @param beanClass the {@code Class} of the bean that the definition is being created for
*/
- public static BeanDefinitionBuilder genericBeanDefinition(Class beanClass) {
+ public static BeanDefinitionBuilder genericBeanDefinition(Class<?> beanClass) {
BeanDefinitionBuilder builder = new BeanDefinitionBuilder();
builder.beanDefinition = new GenericBeanDefinition();
builder.beanDefinition.setBeanClass(beanClass);
@@ -67,7 +67,7 @@ public class BeanDefinitionBuilder {
* Create a new {@code BeanDefinitionBuilder} used to construct a {@link RootBeanDefinition}.
* @param beanClass the {@code Class} of the bean that the definition is being created for
*/
- public static BeanDefinitionBuilder rootBeanDefinition(Class beanClass) {
+ public static BeanDefinitionBuilder rootBeanDefinition(Class<?> beanClass) {
return rootBeanDefinition(beanClass, null);
}
@@ -76,7 +76,7 @@ public class BeanDefinitionBuilder {
* @param beanClass the {@code Class} of the bean that the definition is being created for
* @param factoryMethodName the name of the method to use to construct the bean instance
*/
- public static BeanDefinitionBuilder rootBeanDefinition(Class beanClass, String factoryMethodName) {
+ public static BeanDefinitionBuilder rootBeanDefinition(Class<?> beanClass, String factoryMethodName) {
BeanDefinitionBuilder builder = new BeanDefinitionBuilder();
builder.beanDefinition = new RootBeanDefinition();
builder.beanDefinition.setBeanClass(beanClass);
@@ -167,18 +167,6 @@ public class BeanDefinitionBuilder {
}
/**
- * Set the name of the factory bean to use for this definition.
- * @deprecated since Spring 2.5, in favor of preparing this on the
- * {@link #getRawBeanDefinition() raw BeanDefinition object}
- */
- @Deprecated
- public BeanDefinitionBuilder setFactoryBean(String factoryBean, String factoryMethod) {
- this.beanDefinition.setFactoryBeanName(factoryBean);
- this.beanDefinition.setFactoryMethodName(factoryMethod);
- return this;
- }
-
- /**
* Add an indexed constructor arg value. The current index is tracked internally
* and all additions are at the present point.
* @deprecated since Spring 2.5, in favor of {@link #addConstructorArgValue}
@@ -254,17 +242,6 @@ public class BeanDefinitionBuilder {
}
/**
- * Set whether or not this definition describes a singleton bean,
- * as alternative to {@link #setScope}.
- * @deprecated since Spring 2.5, in favor of {@link #setScope}
- */
- @Deprecated
- public BeanDefinitionBuilder setSingleton(boolean singleton) {
- this.beanDefinition.setSingleton(singleton);
- return this;
- }
-
- /**
* Set whether or not this definition is abstract.
*/
public BeanDefinitionBuilder setAbstract(boolean flag) {
@@ -319,26 +296,4 @@ public class BeanDefinitionBuilder {
return this;
}
- /**
- * Set the source of this definition.
- * @deprecated since Spring 2.5, in favor of preparing this on the
- * {@link #getRawBeanDefinition() raw BeanDefinition object}
- */
- @Deprecated
- public BeanDefinitionBuilder setSource(Object source) {
- this.beanDefinition.setSource(source);
- return this;
- }
-
- /**
- * Set the description associated with this definition.
- * @deprecated since Spring 2.5, in favor of preparing this on the
- * {@link #getRawBeanDefinition() raw BeanDefinition object}
- */
- @Deprecated
- public BeanDefinitionBuilder setResourceDescription(String resourceDescription) {
- this.beanDefinition.setResourceDescription(resourceDescription);
- return this;
- }
-
}
diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionResource.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionResource.java
index 330b6990..7de75a1b 100644
--- a/spring-beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionResource.java
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionResource.java
@@ -64,11 +64,13 @@ class BeanDefinitionResource extends AbstractResource {
return false;
}
+ @Override
public InputStream getInputStream() throws IOException {
throw new FileNotFoundException(
"Resource cannot be opened because it points to " + getDescription());
}
+ @Override
public String getDescription() {
return "BeanDefinition defined in " + this.beanDefinition.getResourceDescription();
}
diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/CglibSubclassingInstantiationStrategy.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/CglibSubclassingInstantiationStrategy.java
index 076e2098..82265bfd 100644
--- a/spring-beans/src/main/java/org/springframework/beans/factory/support/CglibSubclassingInstantiationStrategy.java
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/CglibSubclassingInstantiationStrategy.java
@@ -22,11 +22,14 @@ import java.lang.reflect.Method;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.BeanInstantiationException;
+import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.cglib.core.SpringNamingPolicy;
import org.springframework.cglib.proxy.Callback;
import org.springframework.cglib.proxy.CallbackFilter;
import org.springframework.cglib.proxy.Enhancer;
+import org.springframework.cglib.proxy.Factory;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import org.springframework.cglib.proxy.NoOp;
@@ -39,6 +42,7 @@ import org.springframework.cglib.proxy.NoOp;
*
* @author Rod Johnson
* @author Juergen Hoeller
+ * @author Sam Brannen
* @since 1.1
*/
public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationStrategy {
@@ -63,18 +67,17 @@ public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationSt
@Override
- protected Object instantiateWithMethodInjection(
- RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) {
+ protected Object instantiateWithMethodInjection(RootBeanDefinition beanDefinition, String beanName,
+ BeanFactory owner) {
- // Must generate CGLIB subclass.
- return new CglibSubclassCreator(beanDefinition, owner).instantiate(null, null);
+ return instantiateWithMethodInjection(beanDefinition, beanName, owner, null, null);
}
@Override
- protected Object instantiateWithMethodInjection(
- RootBeanDefinition beanDefinition, String beanName, BeanFactory owner,
- Constructor<?> ctor, Object[] args) {
+ protected Object instantiateWithMethodInjection(RootBeanDefinition beanDefinition, String beanName,
+ BeanFactory owner, Constructor<?> ctor, Object[] args) {
+ // Must generate CGLIB subclass.
return new CglibSubclassCreator(beanDefinition, owner).instantiate(ctor, args);
}
@@ -85,13 +88,14 @@ public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationSt
*/
private static class CglibSubclassCreator {
- private static final Log logger = LogFactory.getLog(CglibSubclassCreator.class);
+ private static final Class<?>[] CALLBACK_TYPES = new Class<?>[]
+ {NoOp.class, LookupOverrideMethodInterceptor.class, ReplaceOverrideMethodInterceptor.class};
private final RootBeanDefinition beanDefinition;
private final BeanFactory owner;
- public CglibSubclassCreator(RootBeanDefinition beanDefinition, BeanFactory owner) {
+ CglibSubclassCreator(RootBeanDefinition beanDefinition, BeanFactory owner) {
this.beanDefinition = beanDefinition;
this.owner = owner;
}
@@ -105,99 +109,148 @@ public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationSt
* Ignored if the {@code ctor} parameter is {@code null}.
* @return new instance of the dynamically generated subclass
*/
- public Object instantiate(Constructor<?> ctor, Object[] args) {
+ Object instantiate(Constructor<?> ctor, Object[] args) {
+ Class<?> subclass = createEnhancedSubclass(this.beanDefinition);
+ Object instance;
+ if (ctor == null) {
+ instance = BeanUtils.instantiate(subclass);
+ }
+ else {
+ try {
+ Constructor<?> enhancedSubclassConstructor = subclass.getConstructor(ctor.getParameterTypes());
+ instance = enhancedSubclassConstructor.newInstance(args);
+ }
+ catch (Exception ex) {
+ throw new BeanInstantiationException(this.beanDefinition.getBeanClass(), String.format(
+ "Failed to invoke constructor for CGLIB enhanced subclass [%s]", subclass.getName()), ex);
+ }
+ }
+ // SPR-10785: set callbacks directly on the instance instead of in the
+ // enhanced class (via the Enhancer) in order to avoid memory leaks.
+ Factory factory = (Factory) instance;
+ factory.setCallbacks(new Callback[] {NoOp.INSTANCE,
+ new LookupOverrideMethodInterceptor(this.beanDefinition, this.owner),
+ new ReplaceOverrideMethodInterceptor(this.beanDefinition, this.owner)});
+ return instance;
+ }
+
+ /**
+ * Create an enhanced subclass of the bean class for the provided bean
+ * definition, using CGLIB.
+ */
+ private Class<?> createEnhancedSubclass(RootBeanDefinition beanDefinition) {
Enhancer enhancer = new Enhancer();
- enhancer.setSuperclass(this.beanDefinition.getBeanClass());
+ enhancer.setSuperclass(beanDefinition.getBeanClass());
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
- enhancer.setCallbackFilter(new CallbackFilterImpl());
- enhancer.setCallbacks(new Callback[] {
- NoOp.INSTANCE,
- new LookupOverrideMethodInterceptor(),
- new ReplaceOverrideMethodInterceptor()
- });
-
- return (ctor != null ? enhancer.create(ctor.getParameterTypes(), args) : enhancer.create());
+ enhancer.setCallbackFilter(new MethodOverrideCallbackFilter(beanDefinition));
+ enhancer.setCallbackTypes(CALLBACK_TYPES);
+ return enhancer.createClass();
}
+ }
- /**
- * Class providing hashCode and equals methods required by CGLIB to
- * ensure that CGLIB doesn't generate a distinct class per bean.
- * Identity is based on class and bean definition.
- */
- private class CglibIdentitySupport {
+ /**
+ * Class providing hashCode and equals methods required by CGLIB to
+ * ensure that CGLIB doesn't generate a distinct class per bean.
+ * Identity is based on class and bean definition.
+ */
+ private static class CglibIdentitySupport {
- /**
- * Exposed for equals method to allow access to enclosing class field
- */
- protected RootBeanDefinition getBeanDefinition() {
- return beanDefinition;
- }
+ private final RootBeanDefinition beanDefinition;
- @Override
- public boolean equals(Object other) {
- return (other.getClass().equals(getClass()) &&
- ((CglibIdentitySupport) other).getBeanDefinition().equals(beanDefinition));
- }
+ CglibIdentitySupport(RootBeanDefinition beanDefinition) {
+ this.beanDefinition = beanDefinition;
+ }
- @Override
- public int hashCode() {
- return beanDefinition.hashCode();
- }
+ RootBeanDefinition getBeanDefinition() {
+ return this.beanDefinition;
}
+ @Override
+ public boolean equals(Object other) {
+ return (getClass().equals(other.getClass()) &&
+ this.beanDefinition.equals(((CglibIdentitySupport) other).beanDefinition));
+ }
- /**
- * CGLIB MethodInterceptor to override methods, replacing them with an
- * implementation that returns a bean looked up in the container.
- */
- private class LookupOverrideMethodInterceptor extends CglibIdentitySupport implements MethodInterceptor {
+ @Override
+ public int hashCode() {
+ return this.beanDefinition.hashCode();
+ }
+ }
+
+
+ /**
+ * CGLIB callback for filtering method interception behavior.
+ */
+ private static class MethodOverrideCallbackFilter extends CglibIdentitySupport implements CallbackFilter {
+
+ private static final Log logger = LogFactory.getLog(MethodOverrideCallbackFilter.class);
- public Object intercept(Object obj, Method method, Object[] args, MethodProxy mp) throws Throwable {
- // Cast is safe, as CallbackFilter filters are used selectively.
- LookupOverride lo = (LookupOverride) beanDefinition.getMethodOverrides().getOverride(method);
- return owner.getBean(lo.getBeanName());
+ MethodOverrideCallbackFilter(RootBeanDefinition beanDefinition) {
+ super(beanDefinition);
+ }
+
+ @Override
+ public int accept(Method method) {
+ MethodOverride methodOverride = getBeanDefinition().getMethodOverrides().getOverride(method);
+ if (logger.isTraceEnabled()) {
+ logger.trace("Override for '" + method.getName() + "' is [" + methodOverride + "]");
+ }
+ if (methodOverride == null) {
+ return PASSTHROUGH;
+ }
+ else if (methodOverride instanceof LookupOverride) {
+ return LOOKUP_OVERRIDE;
}
+ else if (methodOverride instanceof ReplaceOverride) {
+ return METHOD_REPLACER;
+ }
+ throw new UnsupportedOperationException("Unexpected MethodOverride subclass: " +
+ methodOverride.getClass().getName());
}
+ }
- /**
- * CGLIB MethodInterceptor to override methods, replacing them with a call
- * to a generic MethodReplacer.
- */
- private class ReplaceOverrideMethodInterceptor extends CglibIdentitySupport implements MethodInterceptor {
+ /**
+ * CGLIB MethodInterceptor to override methods, replacing them with an
+ * implementation that returns a bean looked up in the container.
+ */
+ private static class LookupOverrideMethodInterceptor extends CglibIdentitySupport implements MethodInterceptor {
- public Object intercept(Object obj, Method method, Object[] args, MethodProxy mp) throws Throwable {
- ReplaceOverride ro = (ReplaceOverride) beanDefinition.getMethodOverrides().getOverride(method);
- // TODO could cache if a singleton for minor performance optimization
- MethodReplacer mr = (MethodReplacer) owner.getBean(ro.getMethodReplacerBeanName());
- return mr.reimplement(obj, method, args);
- }
+ private final BeanFactory owner;
+
+ LookupOverrideMethodInterceptor(RootBeanDefinition beanDefinition, BeanFactory owner) {
+ super(beanDefinition);
+ this.owner = owner;
+ }
+
+ @Override
+ public Object intercept(Object obj, Method method, Object[] args, MethodProxy mp) throws Throwable {
+ // Cast is safe, as CallbackFilter filters are used selectively.
+ LookupOverride lo = (LookupOverride) getBeanDefinition().getMethodOverrides().getOverride(method);
+ return this.owner.getBean(lo.getBeanName());
}
+ }
+ /**
+ * CGLIB MethodInterceptor to override methods, replacing them with a call
+ * to a generic MethodReplacer.
+ */
+ private static class ReplaceOverrideMethodInterceptor extends CglibIdentitySupport implements MethodInterceptor {
- /**
- * CGLIB object to filter method interception behavior.
- */
- private class CallbackFilterImpl extends CglibIdentitySupport implements CallbackFilter {
+ private final BeanFactory owner;
- public int accept(Method method) {
- MethodOverride methodOverride = beanDefinition.getMethodOverrides().getOverride(method);
- if (logger.isTraceEnabled()) {
- logger.trace("Override for '" + method.getName() + "' is [" + methodOverride + "]");
- }
- if (methodOverride == null) {
- return PASSTHROUGH;
- }
- else if (methodOverride instanceof LookupOverride) {
- return LOOKUP_OVERRIDE;
- }
- else if (methodOverride instanceof ReplaceOverride) {
- return METHOD_REPLACER;
- }
- throw new UnsupportedOperationException(
- "Unexpected MethodOverride subclass: " + methodOverride.getClass().getName());
- }
+ ReplaceOverrideMethodInterceptor(RootBeanDefinition beanDefinition, BeanFactory owner) {
+ super(beanDefinition);
+ this.owner = owner;
+ }
+
+ @Override
+ public Object intercept(Object obj, Method method, Object[] args, MethodProxy mp) throws Throwable {
+ ReplaceOverride ro = (ReplaceOverride) getBeanDefinition().getMethodOverrides().getOverride(method);
+ // TODO could cache if a singleton for minor performance optimization
+ MethodReplacer mr = this.owner.getBean(ro.getMethodReplacerBeanName(), MethodReplacer.class);
+ return mr.reimplement(obj, method, args);
}
}
diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/ChildBeanDefinition.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/ChildBeanDefinition.java
index 72ab68bd..87fc66ba 100644
--- a/spring-beans/src/main/java/org/springframework/beans/factory/support/ChildBeanDefinition.java
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/ChildBeanDefinition.java
@@ -17,7 +17,6 @@
package org.springframework.beans.factory.support;
import org.springframework.beans.MutablePropertyValues;
-import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConstructorArgumentValues;
import org.springframework.util.ObjectUtils;
@@ -128,14 +127,16 @@ public class ChildBeanDefinition extends AbstractBeanDefinition {
* @param original the original bean definition to copy from
*/
public ChildBeanDefinition(ChildBeanDefinition original) {
- super((BeanDefinition) original);
+ super(original);
}
+ @Override
public void setParentName(String parentName) {
this.parentName = parentName;
}
+ @Override
public String getParentName() {
return this.parentName;
}
diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/ConstructorResolver.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/ConstructorResolver.java
index 7cb8fd18..d148d444 100644
--- a/spring-beans/src/main/java/org/springframework/beans/factory/support/ConstructorResolver.java
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/ConstructorResolver.java
@@ -68,11 +68,6 @@ import org.springframework.util.StringUtils;
*/
class ConstructorResolver {
- private static final String CONSTRUCTOR_PROPERTIES_CLASS_NAME = "java.beans.ConstructorProperties";
-
- private static final boolean constructorPropertiesAnnotationAvailable =
- ClassUtils.isPresent(CONSTRUCTOR_PROPERTIES_CLASS_NAME, ConstructorResolver.class.getClassLoader());
-
private final AbstractAutowireCapableBeanFactory beanFactory;
@@ -180,10 +175,7 @@ class ConstructorResolver {
ArgumentsHolder argsHolder;
if (resolvedValues != null) {
try {
- String[] paramNames = null;
- if (constructorPropertiesAnnotationAvailable) {
- paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
- }
+ String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
if (paramNames == null) {
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
@@ -267,6 +259,7 @@ class ConstructorResolver {
final Constructor<?> ctorToUse = constructorToUse;
final Object[] argumentsToUse = argsToUse;
beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ @Override
public Object run() {
return beanFactory.getInstantiationStrategy().instantiate(
mbd, beanName, beanFactory, ctorToUse, argumentsToUse);
@@ -582,6 +575,7 @@ class ConstructorResolver {
final Method factoryMethod = factoryMethodToUse;
final Object[] args = argsToUse;
beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ @Override
public Object run() {
return beanFactory.getInstantiationStrategy().instantiate(
mbd, beanName, beanFactory, fb, factoryMethod, args);
@@ -891,7 +885,7 @@ class ConstructorResolver {
/**
- * Inner class to avoid a Java 6 dependency.
+ * Delegate for checking Java 6's {@link ConstructorProperties} annotation.
*/
private static class ConstructorPropertiesChecker {
diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultBeanNameGenerator.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultBeanNameGenerator.java
index 065c4e21..ebd7a702 100644
--- a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultBeanNameGenerator.java
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultBeanNameGenerator.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2007 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.
@@ -27,6 +27,7 @@ import org.springframework.beans.factory.config.BeanDefinition;
*/
public class DefaultBeanNameGenerator implements BeanNameGenerator {
+ @Override
public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
return BeanDefinitionReaderUtils.generateBeanName(definition, registry);
}
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 3823dd70..9e422fcc 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
@@ -29,6 +29,8 @@ import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
@@ -126,6 +128,9 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
/** Whether to allow eager class loading even for lazy-init beans */
private boolean allowEagerClassLoading = true;
+ /** Optional OrderComparator for dependency Lists and arrays */
+ private Comparator<Object> dependencyComparator;
+
/** Resolver to use for checking if a bean definition is an autowire candidate */
private AutowireCandidateResolver autowireCandidateResolver = new SimpleAutowireCandidateResolver();
@@ -207,6 +212,22 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
}
/**
+ * Set a {@link java.util.Comparator} for dependency Lists and arrays.
+ * @see org.springframework.core.OrderComparator
+ * @see org.springframework.core.annotation.AnnotationAwareOrderComparator
+ */
+ public void setDependencyComparator(Comparator<Object> dependencyComparator) {
+ this.dependencyComparator = dependencyComparator;
+ }
+
+ /**
+ * Return the dependency comparator for this BeanFactory (may be {@code null}.
+ */
+ public Comparator<Object> getDependencyComparator() {
+ return this.dependencyComparator;
+ }
+
+ /**
* Set a custom autowire candidate resolver for this BeanFactory to use
* when deciding whether a bean definition should be considered as a
* candidate for autowiring.
@@ -217,6 +238,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
if (System.getSecurityManager() != null) {
final BeanFactory target = this;
AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ @Override
public Object run() {
((BeanFactoryAware) autowireCandidateResolver).setBeanFactory(target);
return null;
@@ -255,6 +277,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
// Implementation of ListableBeanFactory interface
//---------------------------------------------------------------------
+ @Override
public <T> T getBean(Class<T> requiredType) throws BeansException {
Assert.notNull(requiredType, "Required type must not be null");
String[] beanNames = getBeanNamesForType(requiredType);
@@ -303,10 +326,12 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
return this.beanDefinitionMap.containsKey(beanName);
}
+ @Override
public int getBeanDefinitionCount() {
return this.beanDefinitionMap.size();
}
+ @Override
public String[] getBeanDefinitionNames() {
synchronized (this.beanDefinitionMap) {
if (this.frozenBeanDefinitionNames != null) {
@@ -318,10 +343,12 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
}
}
+ @Override
public String[] getBeanNamesForType(Class<?> type) {
return getBeanNamesForType(type, true, true);
}
+ @Override
public String[] getBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {
if (!isConfigurationFrozen() || type == null || !allowEagerInit) {
return doGetBeanNamesForType(type, includeNonSingletons, allowEagerInit);
@@ -427,10 +454,12 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
return (factoryBeanName != null && isFactoryBean(factoryBeanName) && !containsSingleton(factoryBeanName));
}
+ @Override
public <T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException {
return getBeansOfType(type, true, true);
}
+ @Override
public <T> Map<String, T> getBeansOfType(Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)
throws BeansException {
@@ -461,6 +490,24 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
return result;
}
+ @Override
+ public String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType) {
+ List<String> results = new ArrayList<String>();
+ for (String beanName : getBeanDefinitionNames()) {
+ BeanDefinition beanDefinition = getBeanDefinition(beanName);
+ if (!beanDefinition.isAbstract() && findAnnotationOnBean(beanName, annotationType) != null) {
+ results.add(beanName);
+ }
+ }
+ for (String beanName : getSingletonNames()) {
+ if (!results.contains(beanName) && findAnnotationOnBean(beanName, annotationType) != null) {
+ results.add(beanName);
+ }
+ }
+ return results.toArray(new String[results.size()]);
+ }
+
+ @Override
public Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) {
Map<String, Object> results = new LinkedHashMap<String, Object>();
for (String beanName : getBeanDefinitionNames()) {
@@ -483,6 +530,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
* found on the given class itself, as well as checking its raw bean class
* if not found on the exposed bean reference (e.g. in case of a proxy).
*/
+ @Override
public <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
throws NoSuchBeanDefinitionException{
@@ -508,6 +556,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
// Implementation of ConfigurableListableBeanFactory interface
//---------------------------------------------------------------------
+ @Override
public void registerResolvableDependency(Class<?> dependencyType, Object autowiredValue) {
Assert.notNull(dependencyType, "Type must not be null");
if (autowiredValue != null) {
@@ -517,24 +566,37 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
}
}
+ @Override
public boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor)
throws NoSuchBeanDefinitionException {
- // Consider FactoryBeans as autowiring candidates.
- boolean isFactoryBean = (descriptor != null && descriptor.getDependencyType() != null &&
- FactoryBean.class.isAssignableFrom(descriptor.getDependencyType()));
- if (isFactoryBean) {
- beanName = BeanFactoryUtils.transformedBeanName(beanName);
- }
+ return isAutowireCandidate(beanName, descriptor, getAutowireCandidateResolver());
+ }
- if (containsBeanDefinition(beanName)) {
- return isAutowireCandidate(beanName, getMergedLocalBeanDefinition(beanName), descriptor);
+ /**
+ * Determine whether the specified bean definition qualifies as an autowire candidate,
+ * to be injected into other beans which declare a dependency of matching type.
+ * @param beanName the name of the bean definition to check
+ * @param descriptor the descriptor of the dependency to resolve
+ * @param resolver the AutowireCandidateResolver to use for the actual resolution algorithm
+ * @return whether the bean should be considered as autowire candidate
+ */
+ protected boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor, AutowireCandidateResolver resolver)
+ throws NoSuchBeanDefinitionException {
+
+ String beanDefinitionName = BeanFactoryUtils.transformedBeanName(beanName);
+ if (containsBeanDefinition(beanDefinitionName)) {
+ return isAutowireCandidate(beanName, getMergedLocalBeanDefinition(beanDefinitionName), descriptor, resolver);
}
else if (containsSingleton(beanName)) {
- return isAutowireCandidate(beanName, new RootBeanDefinition(getType(beanName)), descriptor);
+ return isAutowireCandidate(beanName, new RootBeanDefinition(getType(beanName)), descriptor, resolver);
}
- else if (getParentBeanFactory() instanceof ConfigurableListableBeanFactory) {
+ else if (getParentBeanFactory() instanceof DefaultListableBeanFactory) {
// No bean definition found in this factory -> delegate to parent.
+ return ((DefaultListableBeanFactory) getParentBeanFactory()).isAutowireCandidate(beanName, descriptor, resolver);
+ }
+ else if (getParentBeanFactory() instanceof ConfigurableListableBeanFactory) {
+ // If no DefaultListableBeanFactory, can't pass the resolver along.
return ((ConfigurableListableBeanFactory) getParentBeanFactory()).isAutowireCandidate(beanName, descriptor);
}
else {
@@ -548,10 +610,14 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
* @param beanName the name of the bean definition to check
* @param mbd the merged bean definition to check
* @param descriptor the descriptor of the dependency to resolve
+ * @param resolver the AutowireCandidateResolver to use for the actual resolution algorithm
* @return whether the bean should be considered as autowire candidate
*/
- protected boolean isAutowireCandidate(String beanName, RootBeanDefinition mbd, DependencyDescriptor descriptor) {
- resolveBeanClass(mbd, beanName);
+ protected boolean isAutowireCandidate(String beanName, RootBeanDefinition mbd,
+ DependencyDescriptor descriptor, AutowireCandidateResolver resolver) {
+
+ String beanDefinitionName = BeanFactoryUtils.transformedBeanName(beanName);
+ resolveBeanClass(mbd, beanDefinitionName);
if (mbd.isFactoryMethodUnique) {
boolean resolve;
synchronized (mbd.constructorArgumentLock) {
@@ -561,8 +627,8 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
new ConstructorResolver(this).resolveFactoryMethodIfPossible(mbd);
}
}
- return getAutowireCandidateResolver().isAutowireCandidate(
- new BeanDefinitionHolder(mbd, beanName, getAliases(beanName)), descriptor);
+ return resolver.isAutowireCandidate(
+ new BeanDefinitionHolder(mbd, beanName, getAliases(beanDefinitionName)), descriptor);
}
@Override
@@ -577,6 +643,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
return bd;
}
+ @Override
public void freezeConfiguration() {
this.configurationFrozen = true;
synchronized (this.beanDefinitionMap) {
@@ -584,6 +651,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
}
}
+ @Override
public boolean isConfigurationFrozen() {
return this.configurationFrozen;
}
@@ -598,9 +666,10 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
return (this.configurationFrozen || super.isBeanEligibleForMetadataCaching(beanName));
}
+ @Override
public void preInstantiateSingletons() throws BeansException {
- if (this.logger.isInfoEnabled()) {
- this.logger.info("Pre-instantiating singletons in " + this);
+ if (this.logger.isDebugEnabled()) {
+ this.logger.debug("Pre-instantiating singletons in " + this);
}
List<String> beanNames;
@@ -619,6 +688,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
+ @Override
public Boolean run() {
return ((SmartFactoryBean<?>) factory).isEagerInit();
}
@@ -644,6 +714,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
// Implementation of BeanDefinitionRegistry interface
//---------------------------------------------------------------------
+ @Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
@@ -670,6 +741,14 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
"Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
"': There is already [" + oldBeanDefinition + "] bound.");
}
+ else if (oldBeanDefinition.getRole() < beanDefinition.getRole()) {
+ // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
+ if (this.logger.isWarnEnabled()) {
+ this.logger.warn("Overriding user-defined bean definition for bean '" + beanName +
+ " with a framework-generated bean definition ': replacing [" +
+ oldBeanDefinition + "] with [" + beanDefinition + "]");
+ }
+ }
else {
if (this.logger.isInfoEnabled()) {
this.logger.info("Overriding bean definition for bean '" + beanName +
@@ -689,6 +768,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
}
}
+ @Override
public void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
Assert.hasText(beanName, "'beanName' must not be empty");
@@ -765,6 +845,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
// Dependency resolution functionality
//---------------------------------------------------------------------
+ @Override
public Object resolveDependency(DependencyDescriptor descriptor, String beanName,
Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException {
@@ -776,13 +857,18 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
return new DependencyProviderFactory().createDependencyProvider(descriptor, beanName);
}
else {
- return doResolveDependency(descriptor, descriptor.getDependencyType(), beanName, autowiredBeanNames, typeConverter);
+ Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(descriptor, beanName);
+ if (result == null) {
+ result = doResolveDependency(descriptor, beanName, autowiredBeanNames, typeConverter);
+ }
+ return result;
}
}
- protected Object doResolveDependency(DependencyDescriptor descriptor, Class<?> type, String beanName,
+ public Object doResolveDependency(DependencyDescriptor descriptor, String beanName,
Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException {
+ Class<?> type = descriptor.getDependencyType();
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
if (value != null) {
if (value instanceof String) {
@@ -798,7 +884,9 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
if (type.isArray()) {
Class<?> componentType = type.getComponentType();
- Map<String, Object> matchingBeans = findAutowireCandidates(beanName, componentType, descriptor);
+ DependencyDescriptor targetDesc = new DependencyDescriptor(descriptor);
+ targetDesc.increaseNestingLevel();
+ Map<String, Object> matchingBeans = findAutowireCandidates(beanName, componentType, targetDesc);
if (matchingBeans.isEmpty()) {
if (descriptor.isRequired()) {
raiseNoSuchBeanDefinitionException(componentType, "array of " + componentType.getName(), descriptor);
@@ -809,7 +897,11 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
autowiredBeanNames.addAll(matchingBeans.keySet());
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
- return converter.convertIfNecessary(matchingBeans.values(), type);
+ Object result = converter.convertIfNecessary(matchingBeans.values(), type);
+ if (this.dependencyComparator != null && result instanceof Object[]) {
+ Arrays.sort((Object[]) result, this.dependencyComparator);
+ }
+ return result;
}
else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {
Class<?> elementType = descriptor.getCollectionType();
@@ -819,7 +911,9 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
}
return null;
}
- Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType, descriptor);
+ DependencyDescriptor targetDesc = new DependencyDescriptor(descriptor);
+ targetDesc.increaseNestingLevel();
+ Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType, targetDesc);
if (matchingBeans.isEmpty()) {
if (descriptor.isRequired()) {
raiseNoSuchBeanDefinitionException(elementType, "collection of " + elementType.getName(), descriptor);
@@ -830,7 +924,11 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
autowiredBeanNames.addAll(matchingBeans.keySet());
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
- return converter.convertIfNecessary(matchingBeans.values(), type);
+ Object result = converter.convertIfNecessary(matchingBeans.values(), type);
+ if (this.dependencyComparator != null && result instanceof List) {
+ Collections.sort((List<?>) result, this.dependencyComparator);
+ }
+ return result;
}
else if (Map.class.isAssignableFrom(type) && type.isInterface()) {
Class<?> keyType = descriptor.getMapKeyType();
@@ -848,7 +946,9 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
}
return null;
}
- Map<String, Object> matchingBeans = findAutowireCandidates(beanName, valueType, descriptor);
+ DependencyDescriptor targetDesc = new DependencyDescriptor(descriptor);
+ targetDesc.increaseNestingLevel();
+ Map<String, Object> matchingBeans = findAutowireCandidates(beanName, valueType, targetDesc);
if (matchingBeans.isEmpty()) {
if (descriptor.isRequired()) {
raiseNoSuchBeanDefinitionException(valueType, "map with value type " + valueType.getName(), descriptor);
@@ -917,10 +1017,18 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
}
}
for (String candidateName : candidateNames) {
- if (!candidateName.equals(beanName) && isAutowireCandidate(candidateName, descriptor)) {
+ if (!isSelfReference(beanName, candidateName) && isAutowireCandidate(candidateName, descriptor)) {
result.put(candidateName, getBean(candidateName));
}
}
+ if (result.isEmpty()) {
+ DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();
+ for (String candidateName : candidateNames) {
+ if (!candidateName.equals(beanName) && isAutowireCandidate(candidateName, fallbackDescriptor)) {
+ result.put(candidateName, getBean(candidateName));
+ }
+ }
+ }
return result;
}
@@ -988,6 +1096,17 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
}
/**
+ * Determine whether the given beanName/candidateName pair indicates a self reference,
+ * i.e. whether the candidate points back to the original bean or to a factory method
+ * on the original bean.
+ */
+ private boolean isSelfReference(String beanName, String candidateName) {
+ return (beanName != null && candidateName != null &&
+ (beanName.equals(candidateName) || (containsBeanDefinition(candidateName) &&
+ beanName.equals(getMergedLocalBeanDefinition(candidateName).getFactoryBeanName()))));
+ }
+
+ /**
* Raise a NoSuchBeanDefinitionException for an unresolvable dependency.
*/
private void raiseNoSuchBeanDefinitionException(
@@ -1079,8 +1198,9 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
this.beanName = beanName;
}
+ @Override
public Object getObject() throws BeansException {
- return doResolveDependency(this.descriptor, this.descriptor.getDependencyType(), this.beanName, null, null);
+ return doResolveDependency(this.descriptor, this.beanName, null, null);
}
}
@@ -1094,6 +1214,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
super(descriptor, beanName);
}
+ @Override
public Object get() throws BeansException {
return getObject();
}
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 4ad522a1..987fb797 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-2013 the original author or authors.
+ * Copyright 2002-2014 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.
@@ -16,7 +16,9 @@
package org.springframework.beans.factory.support;
+import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
@@ -92,11 +94,13 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
/** Set of registered singletons, containing the bean names in registration order */
private final Set<String> registeredSingletons = new LinkedHashSet<String>(64);
- /** Names of beans that are currently in creation (using a ConcurrentHashMap as a Set) */
- private final Map<String, Boolean> singletonsCurrentlyInCreation = new ConcurrentHashMap<String, Boolean>(16);
+ /** Names of beans that are currently in creation */
+ private final Set<String> singletonsCurrentlyInCreation =
+ Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>(16));
- /** Names of beans currently excluded from in creation checks (using a ConcurrentHashMap as a Set) */
- private final Map<String, Boolean> inCreationCheckExclusions = new ConcurrentHashMap<String, Boolean>(16);
+ /** Names of beans currently excluded from in creation checks */
+ private final Set<String> inCreationCheckExclusions =
+ Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>(16));
/** List of suppressed Exceptions, available for associating related causes */
private Set<Exception> suppressedExceptions;
@@ -117,6 +121,7 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<String, Set<String>>(64);
+ @Override
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
Assert.notNull(beanName, "'beanName' must not be null");
synchronized (this.singletonObjects) {
@@ -152,7 +157,7 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
* @param beanName the name of the bean
* @param singletonFactory the factory for the singleton object
*/
- protected void addSingletonFactory(String beanName, ObjectFactory singletonFactory) {
+ protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized (this.singletonObjects) {
if (!this.singletonObjects.containsKey(beanName)) {
@@ -163,6 +168,7 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
}
}
+ @Override
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}
@@ -270,16 +276,19 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
}
}
+ @Override
public boolean containsSingleton(String beanName) {
- return (this.singletonObjects.containsKey(beanName));
+ return this.singletonObjects.containsKey(beanName);
}
+ @Override
public String[] getSingletonNames() {
synchronized (this.singletonObjects) {
return StringUtils.toStringArray(this.registeredSingletons);
}
}
+ @Override
public int getSingletonCount() {
synchronized (this.singletonObjects) {
return this.registeredSingletons.size();
@@ -290,7 +299,7 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
public void setCurrentlyInCreation(String beanName, boolean inCreation) {
Assert.notNull(beanName, "Bean name must not be null");
if (!inCreation) {
- this.inCreationCheckExclusions.put(beanName, Boolean.TRUE);
+ this.inCreationCheckExclusions.add(beanName);
}
else {
this.inCreationCheckExclusions.remove(beanName);
@@ -299,7 +308,7 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
public boolean isCurrentlyInCreation(String beanName) {
Assert.notNull(beanName, "Bean name must not be null");
- return (!this.inCreationCheckExclusions.containsKey(beanName) && isActuallyInCreation(beanName));
+ return (!this.inCreationCheckExclusions.contains(beanName) && isActuallyInCreation(beanName));
}
protected boolean isActuallyInCreation(String beanName) {
@@ -312,18 +321,17 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
* @param beanName the name of the bean
*/
public boolean isSingletonCurrentlyInCreation(String beanName) {
- return this.singletonsCurrentlyInCreation.containsKey(beanName);
+ return this.singletonsCurrentlyInCreation.contains(beanName);
}
/**
* Callback before singleton creation.
- * <p>Default implementation register the singleton as currently in creation.
+ * <p>The default implementation register the singleton as currently in creation.
* @param beanName the name of the singleton about to be created
* @see #isSingletonCurrentlyInCreation
*/
protected void beforeSingletonCreation(String beanName) {
- if (!this.inCreationCheckExclusions.containsKey(beanName) &&
- this.singletonsCurrentlyInCreation.put(beanName, Boolean.TRUE) != null) {
+ if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
}
@@ -335,8 +343,7 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
* @see #isSingletonCurrentlyInCreation
*/
protected void afterSingletonCreation(String beanName) {
- if (!this.inCreationCheckExclusions.containsKey(beanName) &&
- !this.singletonsCurrentlyInCreation.remove(beanName)) {
+ if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
}
}
@@ -405,6 +412,41 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
}
/**
+ * Determine whether the specified dependent bean has been registered as
+ * dependent on the given bean or on any of its transitive dependencies.
+ * @param beanName the name of the bean to check
+ * @param dependentBeanName the name of the dependent bean
+ * @since 4.0
+ */
+ protected boolean isDependent(String beanName, String dependentBeanName) {
+ return isDependent(beanName, dependentBeanName, null);
+ }
+
+ private boolean isDependent(String beanName, String dependentBeanName, Set<String> alreadySeen) {
+ String canonicalName = canonicalName(beanName);
+ if (alreadySeen != null && alreadySeen.contains(beanName)) {
+ return false;
+ }
+ Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
+ if (dependentBeans == null) {
+ return false;
+ }
+ if (dependentBeans.contains(dependentBeanName)) {
+ return true;
+ }
+ for (String transitiveDependency : dependentBeans) {
+ if (alreadySeen == null) {
+ alreadySeen = new HashSet<String>();
+ }
+ alreadySeen.add(beanName);
+ if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
* Determine whether a dependent bean has been registered for the given name.
* @param beanName the name of the bean to check
*/
@@ -440,8 +482,8 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
}
public void destroySingletons() {
- if (logger.isInfoEnabled()) {
- logger.info("Destroying singletons in " + this);
+ if (logger.isDebugEnabled()) {
+ logger.debug("Destroying singletons in " + this);
}
synchronized (this.singletonObjects) {
this.singletonsCurrentlyInDestruction = true;
diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java
index ae394ca7..39721647 100644
--- a/spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/DisposableBeanAdapter.java
@@ -141,6 +141,22 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
/**
* Create a new DisposableBeanAdapter for the given bean.
+ * @param bean the bean instance (never {@code null})
+ * @param postProcessors the List of BeanPostProcessors
+ * (potentially DestructionAwareBeanPostProcessor), if any
+ */
+ public DisposableBeanAdapter(Object bean, List<BeanPostProcessor> postProcessors, AccessControlContext acc) {
+ Assert.notNull(bean, "Disposable bean must not be null");
+ this.bean = bean;
+ this.beanName = null;
+ this.invokeDisposableBean = (this.bean instanceof DisposableBean);
+ this.nonPublicAccessAllowed = true;
+ this.acc = acc;
+ this.beanPostProcessors = filterPostProcessors(postProcessors);
+ }
+
+ /**
+ * Create a new DisposableBeanAdapter for the given bean.
*/
private DisposableBeanAdapter(Object bean, String beanName, boolean invokeDisposableBean,
boolean nonPublicAccessAllowed, String destroyMethodName,
@@ -211,10 +227,12 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
}
+ @Override
public void run() {
destroy();
}
+ @Override
public void destroy() {
if (this.beanPostProcessors != null && !this.beanPostProcessors.isEmpty()) {
for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
@@ -229,6 +247,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
try {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
+ @Override
public Object run() throws Exception {
((DisposableBean) bean).destroy();
return null;
@@ -266,6 +285,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
try {
if (System.getSecurityManager() != null) {
return AccessController.doPrivileged(new PrivilegedAction<Method>() {
+ @Override
public Method run() {
return findDestroyMethod();
}
@@ -306,6 +326,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
try {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ @Override
public Object run() {
ReflectionUtils.makeAccessible(destroyMethod);
return null;
@@ -313,6 +334,7 @@ class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
});
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
+ @Override
public Object run() throws Exception {
destroyMethod.invoke(bean, args);
return null;
diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/FactoryBeanRegistrySupport.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/FactoryBeanRegistrySupport.java
index c5239b5a..53dc1765 100644
--- a/spring-beans/src/main/java/org/springframework/beans/factory/support/FactoryBeanRegistrySupport.java
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/FactoryBeanRegistrySupport.java
@@ -56,6 +56,7 @@ public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanReg
try {
if (System.getSecurityManager() != null) {
return AccessController.doPrivileged(new PrivilegedAction<Class<?>>() {
+ @Override
public Class<?> run() {
return factoryBean.getObjectType();
}
@@ -153,6 +154,7 @@ public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanReg
AccessControlContext acc = getAccessControlContext();
try {
object = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
+ @Override
public Object run() throws Exception {
return factory.getObject();
}
diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/GenericBeanDefinition.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/GenericBeanDefinition.java
index b8f0370c..77c08f67 100644
--- a/spring-beans/src/main/java/org/springframework/beans/factory/support/GenericBeanDefinition.java
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/GenericBeanDefinition.java
@@ -66,10 +66,12 @@ public class GenericBeanDefinition extends AbstractBeanDefinition {
}
+ @Override
public void setParentName(String parentName) {
this.parentName = parentName;
}
+ @Override
public String getParentName() {
return this.parentName;
}
diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/GenericTypeAwareAutowireCandidateResolver.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/GenericTypeAwareAutowireCandidateResolver.java
new file mode 100644
index 00000000..65554ce9
--- /dev/null
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/GenericTypeAwareAutowireCandidateResolver.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright 2002-2013 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.beans.factory.support;
+
+import java.lang.reflect.Method;
+
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.beans.factory.BeanFactoryAware;
+import org.springframework.beans.factory.FactoryBean;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.BeanDefinitionHolder;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.beans.factory.config.DependencyDescriptor;
+import org.springframework.core.ResolvableType;
+import org.springframework.util.ClassUtils;
+
+/**
+ * Basic {@link AutowireCandidateResolver} that performs a full generic type
+ * match with the candidate's type if the dependency is declared as a generic type
+ * (e.g. Repository&lt;Customer&gt;).
+ *
+ * <p>This is the base class for
+ * {@link org.springframework.beans.factory.annotation.QualifierAnnotationAutowireCandidateResolver},
+ * providing an implementation all non-annotation-based resolution steps at this level.
+ *
+ * @author Juergen Hoeller
+ * @since 4.0
+ */
+public class GenericTypeAwareAutowireCandidateResolver implements AutowireCandidateResolver, BeanFactoryAware {
+
+ private BeanFactory beanFactory;
+
+
+ @Override
+ public void setBeanFactory(BeanFactory beanFactory) {
+ this.beanFactory = beanFactory;
+ }
+
+ protected final BeanFactory getBeanFactory() {
+ return this.beanFactory;
+ }
+
+
+ @Override
+ public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
+ if (!bdHolder.getBeanDefinition().isAutowireCandidate()) {
+ // if explicitly false, do not proceed with any other checks
+ return false;
+ }
+ return (descriptor == null || checkGenericTypeMatch(bdHolder, descriptor));
+ }
+
+ /**
+ * Match the given dependency type with its generic type information against the given
+ * candidate bean definition.
+ */
+ protected boolean checkGenericTypeMatch(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
+ ResolvableType dependencyType = descriptor.getResolvableType();
+ if (dependencyType.getType() instanceof Class) {
+ // No generic type -> we know it's a Class type-match, so no need to check again.
+ return true;
+ }
+ ResolvableType targetType = null;
+ RootBeanDefinition rbd = null;
+ if (bdHolder.getBeanDefinition() instanceof RootBeanDefinition) {
+ rbd = (RootBeanDefinition) bdHolder.getBeanDefinition();
+ }
+ if (rbd != null) {
+ // First, check factory method return type, if applicable
+ targetType = getReturnTypeForFactoryMethod(rbd, descriptor);
+ if (targetType == null) {
+ RootBeanDefinition dbd = getResolvedDecoratedDefinition(rbd);
+ if (dbd != null) {
+ targetType = getReturnTypeForFactoryMethod(dbd, descriptor);
+ }
+ }
+ }
+ if (targetType == null) {
+ // Regular case: straight bean instance, with BeanFactory available.
+ if (this.beanFactory != null) {
+ Class<?> beanType = this.beanFactory.getType(bdHolder.getBeanName());
+ if (beanType != null) {
+ targetType = ResolvableType.forClass(ClassUtils.getUserClass(beanType));
+ }
+ }
+ // Fallback: no BeanFactory set, or no type resolvable through it
+ // -> best-effort match against the target class if applicable.
+ if (targetType == null && rbd != null && rbd.hasBeanClass() && rbd.getFactoryMethodName() == null) {
+ Class<?> beanClass = rbd.getBeanClass();
+ if (!FactoryBean.class.isAssignableFrom(beanClass)) {
+ targetType = ResolvableType.forClass(ClassUtils.getUserClass(beanClass));
+ }
+ }
+ }
+ if (targetType == null || (descriptor.fallbackMatchAllowed() && targetType.hasUnresolvableGenerics())) {
+ return true;
+ }
+ // Full check for complex generic type match...
+ return dependencyType.isAssignableFrom(targetType);
+ }
+
+ protected RootBeanDefinition getResolvedDecoratedDefinition(RootBeanDefinition rbd) {
+ BeanDefinitionHolder decDef = rbd.getDecoratedDefinition();
+ if (decDef != null && this.beanFactory instanceof ConfigurableListableBeanFactory) {
+ ConfigurableListableBeanFactory clbf = (ConfigurableListableBeanFactory) this.beanFactory;
+ if (clbf.containsBeanDefinition(decDef.getBeanName())) {
+ BeanDefinition dbd = clbf.getMergedBeanDefinition(decDef.getBeanName());
+ if (dbd instanceof RootBeanDefinition) {
+ return (RootBeanDefinition) dbd;
+ }
+ }
+ }
+ return null;
+ }
+
+ protected ResolvableType getReturnTypeForFactoryMethod(RootBeanDefinition rbd, DependencyDescriptor descriptor) {
+ // Should typically be set for any kind of factory method, since the BeanFactory
+ // pre-resolves them before reaching out to the AutowireCandidateResolver...
+ Class<?> preResolved = rbd.resolvedFactoryMethodReturnType;
+ if (preResolved != null) {
+ return ResolvableType.forClass(preResolved);
+ }
+ else {
+ Method resolvedFactoryMethod = rbd.getResolvedFactoryMethod();
+ if (resolvedFactoryMethod != null) {
+ if (descriptor.getDependencyType().isAssignableFrom(resolvedFactoryMethod.getReturnType())) {
+ // Only use factory method metadata if the return type is actually expressive enough
+ // for our dependency. Otherwise, the returned instance type may have matched instead
+ // in case of a singleton instance having been registered with the container already.
+ return ResolvableType.forMethodReturnType(resolvedFactoryMethod);
+ }
+ }
+ return null;
+ }
+ }
+
+
+ /**
+ * This implementation always returns {@code null}, leaving suggested value support up
+ * to subclasses.
+ */
+ @Override
+ public Object getSuggestedValue(DependencyDescriptor descriptor) {
+ return null;
+ }
+
+ /**
+ * This implementation always returns {@code null}, leaving lazy resolution support up
+ * to subclasses.
+ */
+ @Override
+ public Object getLazyResolutionProxyIfNecessary(DependencyDescriptor descriptor, String beanName) {
+ return null;
+ }
+
+}
diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/LookupOverride.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/LookupOverride.java
index 6aa560ce..4d4f62f7 100644
--- a/spring-beans/src/main/java/org/springframework/beans/factory/support/LookupOverride.java
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/LookupOverride.java
@@ -77,7 +77,7 @@ public class LookupOverride extends MethodOverride {
@Override
public String toString() {
- return "LookupOverride for method '" + getMethodName() + "'; will return bean '" + this.beanName + "'";
+ return "LookupOverride for method '" + getMethodName() + "'";
}
}
diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/ManagedArray.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/ManagedArray.java
index e7e7ec7d..e47d5dbe 100644
--- a/spring-beans/src/main/java/org/springframework/beans/factory/support/ManagedArray.java
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/ManagedArray.java
@@ -29,7 +29,7 @@ import org.springframework.util.Assert;
public class ManagedArray extends ManagedList<Object> {
/** Resolved element type for runtime creation of the target array */
- volatile Class resolvedElementType;
+ volatile Class<?> resolvedElementType;
/**
diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/ManagedList.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/ManagedList.java
index 5c9aa550..2a25830e 100644
--- a/spring-beans/src/main/java/org/springframework/beans/factory/support/ManagedList.java
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/ManagedList.java
@@ -57,6 +57,7 @@ public class ManagedList<E> extends ArrayList<E> implements Mergeable, BeanMetad
this.source = source;
}
+ @Override
public Object getSource() {
return this.source;
}
@@ -83,10 +84,12 @@ public class ManagedList<E> extends ArrayList<E> implements Mergeable, BeanMetad
this.mergeEnabled = mergeEnabled;
}
+ @Override
public boolean isMergeEnabled() {
return this.mergeEnabled;
}
+ @Override
@SuppressWarnings("unchecked")
public List<E> merge(Object parent) {
if (!this.mergeEnabled) {
@@ -99,7 +102,7 @@ public class ManagedList<E> extends ArrayList<E> implements Mergeable, BeanMetad
throw new IllegalArgumentException("Cannot merge with object of type [" + parent.getClass() + "]");
}
List<E> merged = new ManagedList<E>();
- merged.addAll((List) parent);
+ merged.addAll((List<E>) parent);
merged.addAll(this);
return merged;
}
diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/ManagedMap.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/ManagedMap.java
index 4529b714..3cc4b986 100644
--- a/spring-beans/src/main/java/org/springframework/beans/factory/support/ManagedMap.java
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/ManagedMap.java
@@ -58,6 +58,7 @@ public class ManagedMap<K, V> extends LinkedHashMap<K, V> implements Mergeable,
this.source = source;
}
+ @Override
public Object getSource() {
return this.source;
}
@@ -98,10 +99,12 @@ public class ManagedMap<K, V> extends LinkedHashMap<K, V> implements Mergeable,
this.mergeEnabled = mergeEnabled;
}
+ @Override
public boolean isMergeEnabled() {
return this.mergeEnabled;
}
+ @Override
@SuppressWarnings("unchecked")
public Object merge(Object parent) {
if (!this.mergeEnabled) {
@@ -114,7 +117,7 @@ public class ManagedMap<K, V> extends LinkedHashMap<K, V> implements Mergeable,
throw new IllegalArgumentException("Cannot merge with object of type [" + parent.getClass() + "]");
}
Map<K, V> merged = new ManagedMap<K, V>();
- merged.putAll((Map) parent);
+ merged.putAll((Map<K, V>) parent);
merged.putAll(this);
return merged;
}
diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/ManagedProperties.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/ManagedProperties.java
index 95b44472..dadaac3e 100644
--- a/spring-beans/src/main/java/org/springframework/beans/factory/support/ManagedProperties.java
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/ManagedProperties.java
@@ -45,6 +45,7 @@ public class ManagedProperties extends Properties implements Mergeable, BeanMeta
this.source = source;
}
+ @Override
public Object getSource() {
return this.source;
}
@@ -57,11 +58,13 @@ public class ManagedProperties extends Properties implements Mergeable, BeanMeta
this.mergeEnabled = mergeEnabled;
}
+ @Override
public boolean isMergeEnabled() {
return this.mergeEnabled;
}
+ @Override
public Object merge(Object parent) {
if (!this.mergeEnabled) {
throw new IllegalStateException("Not allowed to merge when the 'mergeEnabled' property is set to 'false'");
diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/ManagedSet.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/ManagedSet.java
index 654cadc9..dc6f0e0c 100644
--- a/spring-beans/src/main/java/org/springframework/beans/factory/support/ManagedSet.java
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/ManagedSet.java
@@ -56,6 +56,7 @@ public class ManagedSet<E> extends LinkedHashSet<E> implements Mergeable, BeanMe
this.source = source;
}
+ @Override
public Object getSource() {
return this.source;
}
@@ -82,10 +83,12 @@ public class ManagedSet<E> extends LinkedHashSet<E> implements Mergeable, BeanMe
this.mergeEnabled = mergeEnabled;
}
+ @Override
public boolean isMergeEnabled() {
return this.mergeEnabled;
}
+ @Override
@SuppressWarnings("unchecked")
public Set<E> merge(Object parent) {
if (!this.mergeEnabled) {
@@ -98,7 +101,7 @@ public class ManagedSet<E> extends LinkedHashSet<E> implements Mergeable, BeanMe
throw new IllegalArgumentException("Cannot merge with object of type [" + parent.getClass() + "]");
}
Set<E> merged = new ManagedSet<E>();
- merged.addAll((Set) parent);
+ merged.addAll((Set<E>) parent);
merged.addAll(this);
return merged;
}
diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/MethodOverride.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/MethodOverride.java
index 33f969db..bf11af7e 100644
--- a/spring-beans/src/main/java/org/springframework/beans/factory/support/MethodOverride.java
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/MethodOverride.java
@@ -86,6 +86,7 @@ public abstract class MethodOverride implements BeanMetadataElement {
this.source = source;
}
+ @Override
public Object getSource() {
return this.source;
}
diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/PropertiesBeanDefinitionReader.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/PropertiesBeanDefinitionReader.java
index d51dc55f..454b2c35 100644
--- a/spring-beans/src/main/java/org/springframework/beans/factory/support/PropertiesBeanDefinitionReader.java
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/PropertiesBeanDefinitionReader.java
@@ -204,6 +204,7 @@ public class PropertiesBeanDefinitionReader extends AbstractBeanDefinitionReader
* @throws BeanDefinitionStoreException in case of loading or parsing errors
* @see #loadBeanDefinitions(org.springframework.core.io.Resource, String)
*/
+ @Override
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
return loadBeanDefinitions(new EncodedResource(resource), null);
}
@@ -289,9 +290,9 @@ public class PropertiesBeanDefinitionReader extends AbstractBeanDefinitionReader
public int registerBeanDefinitions(ResourceBundle rb, String prefix) throws BeanDefinitionStoreException {
// Simply create a map and call overloaded method.
Map<String, Object> map = new HashMap<String, Object>();
- Enumeration keys = rb.getKeys();
+ Enumeration<String> keys = rb.getKeys();
while (keys.hasMoreElements()) {
- String key = (String) keys.nextElement();
+ String key = keys.nextElement();
map.put(key, rb.getObject(key));
}
return registerBeanDefinitions(map, prefix);
@@ -308,7 +309,7 @@ public class PropertiesBeanDefinitionReader extends AbstractBeanDefinitionReader
* @throws BeansException in case of loading or parsing errors
* @see #registerBeanDefinitions(java.util.Map, String, String)
*/
- public int registerBeanDefinitions(Map map) throws BeansException {
+ public int registerBeanDefinitions(Map<?, ?> map) throws BeansException {
return registerBeanDefinitions(map, null);
}
@@ -323,7 +324,7 @@ public class PropertiesBeanDefinitionReader extends AbstractBeanDefinitionReader
* @return the number of bean definitions found
* @throws BeansException in case of loading or parsing errors
*/
- public int registerBeanDefinitions(Map map, String prefix) throws BeansException {
+ public int registerBeanDefinitions(Map<?, ?> map, String prefix) throws BeansException {
return registerBeanDefinitions(map, prefix, "Map " + map);
}
@@ -341,7 +342,7 @@ public class PropertiesBeanDefinitionReader extends AbstractBeanDefinitionReader
* @throws BeansException in case of loading or parsing errors
* @see #registerBeanDefinitions(Map, String)
*/
- public int registerBeanDefinitions(Map map, String prefix, String resourceDescription)
+ public int registerBeanDefinitions(Map<?, ?> map, String prefix, String resourceDescription)
throws BeansException {
if (prefix == null) {
@@ -412,7 +413,7 @@ public class PropertiesBeanDefinitionReader extends AbstractBeanDefinitionReader
ConstructorArgumentValues cas = new ConstructorArgumentValues();
MutablePropertyValues pvs = new MutablePropertyValues();
- for (Map.Entry entry : map.entrySet()) {
+ for (Map.Entry<?, ?> entry : map.entrySet()) {
String key = StringUtils.trimWhitespace((String) entry.getKey());
if (key.startsWith(prefix + SEPARATOR)) {
String property = key.substring(prefix.length() + SEPARATOR.length());
@@ -501,7 +502,7 @@ public class PropertiesBeanDefinitionReader extends AbstractBeanDefinitionReader
* Reads the value of the entry. Correctly interprets bean references for
* values that are prefixed with an asterisk.
*/
- private Object readValue(Map.Entry entry) {
+ private Object readValue(Map.Entry<? ,?> entry) {
Object val = entry.getValue();
if (val instanceof String) {
String strVal = (String) val;
diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/ReplaceOverride.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/ReplaceOverride.java
index 55ef696b..b3eb9b9e 100644
--- a/spring-beans/src/main/java/org/springframework/beans/factory/support/ReplaceOverride.java
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/ReplaceOverride.java
@@ -112,8 +112,7 @@ public class ReplaceOverride extends MethodOverride {
@Override
public String toString() {
- return "Replace override for method '" + getMethodName() + "; will call bean '" +
- this.methodReplacerBeanName + "'";
+ return "Replace override for method '" + getMethodName() + "'";
}
}
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 c209e49f..d2ac971c 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
@@ -61,6 +61,9 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
/** Package-visible field for caching the resolved constructor or factory method */
Object resolvedConstructorOrFactoryMethod;
+ /** Package-visible field for caching the return type of a generically typed factory method */
+ volatile Class<?> resolvedFactoryMethodReturnType;
+
/** Package-visible field that marks the constructor arguments as resolved */
boolean constructorArgumentsResolved = false;
@@ -110,33 +113,6 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
}
/**
- * Create a new RootBeanDefinition with the given singleton status.
- * @param beanClass the class of the bean to instantiate
- * @param singleton the singleton status of the bean
- * @deprecated since Spring 2.5, in favor of {@link #setScope}
- */
- @Deprecated
- public RootBeanDefinition(Class beanClass, boolean singleton) {
- super();
- setBeanClass(beanClass);
- setSingleton(singleton);
- }
-
- /**
- * Create a new RootBeanDefinition for a singleton,
- * using the given autowire mode.
- * @param beanClass the class of the bean to instantiate
- * @param autowireMode by name or type, using the constants in this interface
- * @deprecated as of Spring 3.0, in favor of {@link #setAutowireMode} usage
- */
- @Deprecated
- public RootBeanDefinition(Class beanClass, int autowireMode) {
- super();
- setBeanClass(beanClass);
- setAutowireMode(autowireMode);
- }
-
- /**
* Create a new RootBeanDefinition for a singleton,
* using the given autowire mode.
* @param beanClass the class of the bean to instantiate
@@ -155,34 +131,6 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
/**
* Create a new RootBeanDefinition for a singleton,
- * providing property values.
- * @param beanClass the class of the bean to instantiate
- * @param pvs the property values to apply
- * @deprecated as of Spring 3.0, in favor of {@link #getPropertyValues} usage
- */
- @Deprecated
- public RootBeanDefinition(Class beanClass, MutablePropertyValues pvs) {
- super(null, pvs);
- setBeanClass(beanClass);
- }
-
- /**
- * Create a new RootBeanDefinition with the given singleton status,
- * providing property values.
- * @param beanClass the class of the bean to instantiate
- * @param pvs the property values to apply
- * @param singleton the singleton status of the bean
- * @deprecated since Spring 2.5, in favor of {@link #setScope}
- */
- @Deprecated
- public RootBeanDefinition(Class beanClass, MutablePropertyValues pvs, boolean singleton) {
- super(null, pvs);
- setBeanClass(beanClass);
- setSingleton(singleton);
- }
-
- /**
- * Create a new RootBeanDefinition for a singleton,
* providing constructor arguments and property values.
* @param beanClass the class of the bean to instantiate
* @param cargs the constructor argument values to apply
@@ -222,7 +170,7 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
* @param original the original bean definition to copy from
*/
public RootBeanDefinition(RootBeanDefinition original) {
- super((BeanDefinition) original);
+ super(original);
this.allowCaching = original.allowCaching;
this.decoratedDefinition = original.decoratedDefinition;
this.targetType = original.targetType;
@@ -239,10 +187,12 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
}
+ @Override
public String getParentName() {
return null;
}
+ @Override
public void setParentName(String parentName) {
if (parentName != null) {
throw new IllegalArgumentException("Root bean cannot be changed into a child bean with parent reference");
diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleAutowireCandidateResolver.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleAutowireCandidateResolver.java
index 735def66..4d29b95b 100644
--- a/spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleAutowireCandidateResolver.java
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleAutowireCandidateResolver.java
@@ -1,6 +1,5 @@
-
/*
- * Copyright 2002-2010 the original author or authors.
+ * Copyright 2002-2013 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.
@@ -37,12 +36,19 @@ public class SimpleAutowireCandidateResolver implements AutowireCandidateResolve
* <p>To be considered a candidate the bean's <em>autowire-candidate</em>
* attribute must not have been set to 'false'.
*/
+ @Override
public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
return bdHolder.getBeanDefinition().isAutowireCandidate();
}
+ @Override
public Object getSuggestedValue(DependencyDescriptor descriptor) {
return null;
}
+ @Override
+ public Object getLazyResolutionProxyIfNecessary(DependencyDescriptor descriptor, String beanName) {
+ return null;
+ }
+
}
diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleBeanDefinitionRegistry.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleBeanDefinitionRegistry.java
index 8a42fc23..b792c6cd 100644
--- a/spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleBeanDefinitionRegistry.java
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleBeanDefinitionRegistry.java
@@ -40,6 +40,7 @@ public class SimpleBeanDefinitionRegistry extends SimpleAliasRegistry implements
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(64);
+ @Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
@@ -48,12 +49,14 @@ public class SimpleBeanDefinitionRegistry extends SimpleAliasRegistry implements
this.beanDefinitionMap.put(beanName, beanDefinition);
}
+ @Override
public void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
if (this.beanDefinitionMap.remove(beanName) == null) {
throw new NoSuchBeanDefinitionException(beanName);
}
}
+ @Override
public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
BeanDefinition bd = this.beanDefinitionMap.get(beanName);
if (bd == null) {
@@ -62,18 +65,22 @@ public class SimpleBeanDefinitionRegistry extends SimpleAliasRegistry implements
return bd;
}
+ @Override
public boolean containsBeanDefinition(String beanName) {
return this.beanDefinitionMap.containsKey(beanName);
}
+ @Override
public String[] getBeanDefinitionNames() {
return StringUtils.toStringArray(this.beanDefinitionMap.keySet());
}
+ @Override
public int getBeanDefinitionCount() {
return this.beanDefinitionMap.size();
}
+ @Override
public boolean isBeanNameInUse(String beanName) {
return isAlias(beanName) || containsBeanDefinition(beanName);
}
diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleInstantiationStrategy.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleInstantiationStrategy.java
index cdc12a1d..26ef2127 100644
--- a/spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleInstantiationStrategy.java
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleInstantiationStrategy.java
@@ -55,6 +55,7 @@ public class SimpleInstantiationStrategy implements InstantiationStrategy {
}
+ @Override
public Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
if (beanDefinition.getMethodOverrides().isEmpty()) {
@@ -68,7 +69,8 @@ public class SimpleInstantiationStrategy implements InstantiationStrategy {
}
try {
if (System.getSecurityManager() != null) {
- constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor>() {
+ constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor<?>>() {
+ @Override
public Constructor<?> run() throws Exception {
return clazz.getDeclaredConstructor((Class[]) null);
}
@@ -105,6 +107,7 @@ public class SimpleInstantiationStrategy implements InstantiationStrategy {
"Method Injection not supported in SimpleInstantiationStrategy");
}
+ @Override
public Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner,
final Constructor<?> ctor, Object[] args) {
@@ -112,6 +115,7 @@ public class SimpleInstantiationStrategy implements InstantiationStrategy {
if (System.getSecurityManager() != null) {
// use own privileged to change accessibility (when security is on)
AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ @Override
public Object run() {
ReflectionUtils.makeAccessible(ctor);
return null;
@@ -138,12 +142,14 @@ public class SimpleInstantiationStrategy implements InstantiationStrategy {
"Method Injection not supported in SimpleInstantiationStrategy");
}
+ @Override
public Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner,
Object factoryBean, final Method factoryMethod, Object[] args) {
try {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ @Override
public Object run() {
ReflectionUtils.makeAccessible(factoryMethod);
return null;
diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleSecurityContextProvider.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleSecurityContextProvider.java
index edb954ae..15aed4c5 100644
--- a/spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleSecurityContextProvider.java
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleSecurityContextProvider.java
@@ -51,6 +51,7 @@ public class SimpleSecurityContextProvider implements SecurityContextProvider {
}
+ @Override
public AccessControlContext getAccessControlContext() {
return (this.acc != null ? acc : AccessController.getContext());
}
diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/StaticListableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/StaticListableBeanFactory.java
index 16681cc4..529fbd7d 100644
--- a/spring-beans/src/main/java/org/springframework/beans/factory/support/StaticListableBeanFactory.java
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/StaticListableBeanFactory.java
@@ -76,6 +76,7 @@ public class StaticListableBeanFactory implements ListableBeanFactory {
// Implementation of BeanFactory interface
//---------------------------------------------------------------------
+ @Override
public Object getBean(String name) throws BeansException {
String beanName = BeanFactoryUtils.transformedBeanName(name);
Object bean = this.beans.get(beanName);
@@ -104,6 +105,7 @@ public class StaticListableBeanFactory implements ListableBeanFactory {
}
}
+ @Override
@SuppressWarnings("unchecked")
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
Object bean = getBean(name);
@@ -113,6 +115,7 @@ public class StaticListableBeanFactory implements ListableBeanFactory {
return (T) bean;
}
+ @Override
public <T> T getBean(Class<T> requiredType) throws BeansException {
String[] beanNames = getBeanNamesForType(requiredType);
if (beanNames.length == 1) {
@@ -126,6 +129,7 @@ public class StaticListableBeanFactory implements ListableBeanFactory {
}
}
+ @Override
public Object getBean(String name, Object... args) throws BeansException {
if (args != null) {
throw new UnsupportedOperationException(
@@ -134,16 +138,19 @@ public class StaticListableBeanFactory implements ListableBeanFactory {
return getBean(name);
}
+ @Override
public boolean containsBean(String name) {
return this.beans.containsKey(name);
}
+ @Override
public boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
Object bean = getBean(name);
// In case of FactoryBean, return singleton status of created object.
return (bean instanceof FactoryBean && ((FactoryBean<?>) bean).isSingleton());
}
+ @Override
public boolean isPrototype(String name) throws NoSuchBeanDefinitionException {
Object bean = getBean(name);
// In case of FactoryBean, return prototype status of created object.
@@ -151,11 +158,13 @@ public class StaticListableBeanFactory implements ListableBeanFactory {
(bean instanceof FactoryBean && !((FactoryBean<?>) bean).isSingleton()));
}
+ @Override
public boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException {
Class<?> type = getType(name);
return (targetType == null || (type != null && targetType.isAssignableFrom(type)));
}
+ @Override
public Class<?> getType(String name) throws NoSuchBeanDefinitionException {
String beanName = BeanFactoryUtils.transformedBeanName(name);
@@ -172,6 +181,7 @@ public class StaticListableBeanFactory implements ListableBeanFactory {
return bean.getClass();
}
+ @Override
public String[] getAliases(String name) {
return new String[0];
}
@@ -181,22 +191,27 @@ public class StaticListableBeanFactory implements ListableBeanFactory {
// Implementation of ListableBeanFactory interface
//---------------------------------------------------------------------
+ @Override
public boolean containsBeanDefinition(String name) {
return this.beans.containsKey(name);
}
+ @Override
public int getBeanDefinitionCount() {
return this.beans.size();
}
+ @Override
public String[] getBeanDefinitionNames() {
return StringUtils.toStringArray(this.beans.keySet());
}
+ @Override
public String[] getBeanNamesForType(Class<?> type) {
return getBeanNamesForType(type, true, true);
}
+ @Override
public String[] getBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean includeFactoryBeans) {
boolean isFactoryType = (type != null && FactoryBean.class.isAssignableFrom(type));
List<String> matches = new ArrayList<String>();
@@ -219,10 +234,12 @@ public class StaticListableBeanFactory implements ListableBeanFactory {
return StringUtils.toStringArray(matches);
}
+ @Override
public <T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException {
return getBeansOfType(type, true, true);
}
+ @Override
@SuppressWarnings("unchecked")
public <T> Map<String, T> getBeansOfType(Class<T> type, boolean includeNonSingletons, boolean includeFactoryBeans)
throws BeansException {
@@ -259,6 +276,18 @@ public class StaticListableBeanFactory implements ListableBeanFactory {
return matches;
}
+ @Override
+ public String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType) {
+ List<String> results = new ArrayList<String>();
+ for (String beanName : this.beans.keySet()) {
+ if (findAnnotationOnBean(beanName, annotationType) != null) {
+ results.add(beanName);
+ }
+ }
+ return results.toArray(new String[results.size()]);
+ }
+
+ @Override
public Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType)
throws BeansException {
@@ -271,7 +300,10 @@ public class StaticListableBeanFactory implements ListableBeanFactory {
return results;
}
- public <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType) {
+ @Override
+ public <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
+ throws NoSuchBeanDefinitionException{
+
return AnnotationUtils.findAnnotation(getType(beanName), annotationType);
}