|
|
|
@ -21,13 +21,14 @@ import java.io.NotSerializableException; |
|
|
|
import java.io.ObjectInputStream; |
|
|
|
import java.io.ObjectInputStream; |
|
|
|
import java.io.ObjectStreamException; |
|
|
|
import java.io.ObjectStreamException; |
|
|
|
import java.io.Serializable; |
|
|
|
import java.io.Serializable; |
|
|
|
|
|
|
|
|
|
|
|
import java.lang.annotation.Annotation; |
|
|
|
import java.lang.annotation.Annotation; |
|
|
|
import java.lang.ref.Reference; |
|
|
|
import java.lang.ref.Reference; |
|
|
|
import java.lang.ref.WeakReference; |
|
|
|
import java.lang.ref.WeakReference; |
|
|
|
import java.lang.reflect.ParameterizedType; |
|
|
|
|
|
|
|
import java.lang.reflect.Type; |
|
|
|
|
|
|
|
import java.security.AccessController; |
|
|
|
import java.security.AccessController; |
|
|
|
import java.security.PrivilegedAction; |
|
|
|
import java.security.PrivilegedAction; |
|
|
|
|
|
|
|
|
|
|
|
import java.util.ArrayList; |
|
|
|
import java.util.ArrayList; |
|
|
|
import java.util.Arrays; |
|
|
|
import java.util.Arrays; |
|
|
|
import java.util.Collection; |
|
|
|
import java.util.Collection; |
|
|
|
@ -38,6 +39,7 @@ import java.util.List; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.Set; |
|
|
|
import java.util.Set; |
|
|
|
import java.util.concurrent.ConcurrentHashMap; |
|
|
|
import java.util.concurrent.ConcurrentHashMap; |
|
|
|
|
|
|
|
|
|
|
|
import javax.inject.Provider; |
|
|
|
import javax.inject.Provider; |
|
|
|
|
|
|
|
|
|
|
|
import org.springframework.beans.BeansException; |
|
|
|
import org.springframework.beans.BeansException; |
|
|
|
@ -90,6 +92,7 @@ import org.springframework.util.StringUtils; |
|
|
|
* @author Juergen Hoeller |
|
|
|
* @author Juergen Hoeller |
|
|
|
* @author Sam Brannen |
|
|
|
* @author Sam Brannen |
|
|
|
* @author Costin Leau |
|
|
|
* @author Costin Leau |
|
|
|
|
|
|
|
* @author Chris Beams |
|
|
|
* @since 16 April 2001 |
|
|
|
* @since 16 April 2001 |
|
|
|
* @see StaticListableBeanFactory |
|
|
|
* @see StaticListableBeanFactory |
|
|
|
* @see PropertiesBeanDefinitionReader |
|
|
|
* @see PropertiesBeanDefinitionReader |
|
|
|
@ -98,7 +101,7 @@ import org.springframework.util.StringUtils; |
|
|
|
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory |
|
|
|
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory |
|
|
|
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable { |
|
|
|
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable { |
|
|
|
|
|
|
|
|
|
|
|
private static Class javaxInjectProviderClass = null; |
|
|
|
private static Class<?> javaxInjectProviderClass = null; |
|
|
|
|
|
|
|
|
|
|
|
static { |
|
|
|
static { |
|
|
|
ClassLoader cl = DefaultListableBeanFactory.class.getClassLoader(); |
|
|
|
ClassLoader cl = DefaultListableBeanFactory.class.getClassLoader(); |
|
|
|
@ -128,11 +131,17 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto |
|
|
|
private AutowireCandidateResolver autowireCandidateResolver = new SimpleAutowireCandidateResolver(); |
|
|
|
private AutowireCandidateResolver autowireCandidateResolver = new SimpleAutowireCandidateResolver(); |
|
|
|
|
|
|
|
|
|
|
|
/** Map from dependency type to corresponding autowired value */ |
|
|
|
/** Map from dependency type to corresponding autowired value */ |
|
|
|
private final Map<Class, Object> resolvableDependencies = new HashMap<Class, Object>(); |
|
|
|
private final Map<Class<?>, Object> resolvableDependencies = new HashMap<Class<?>, Object>(); |
|
|
|
|
|
|
|
|
|
|
|
/** Map of bean definition objects, keyed by bean name */ |
|
|
|
/** Map of bean definition objects, keyed by bean name */ |
|
|
|
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(); |
|
|
|
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** Map of singleton bean names keyed by bean class */ |
|
|
|
|
|
|
|
private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<Class<?>, String[]>(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** Map of non-singleton bean names keyed by bean class */ |
|
|
|
|
|
|
|
private final Map<Class<?>, String[]> nonSingletonBeanNamesByType = new ConcurrentHashMap<Class<?>, String[]>(); |
|
|
|
|
|
|
|
|
|
|
|
/** List of bean definition names, in registration order */ |
|
|
|
/** List of bean definition names, in registration order */ |
|
|
|
private final List<String> beanDefinitionNames = new ArrayList<String>(); |
|
|
|
private final List<String> beanDefinitionNames = new ArrayList<String>(); |
|
|
|
|
|
|
|
|
|
|
|
@ -294,11 +303,26 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public String[] getBeanNamesForType(Class type) { |
|
|
|
public String[] getBeanNamesForType(Class<?> type) { |
|
|
|
return getBeanNamesForType(type, true, true); |
|
|
|
return getBeanNamesForType(type, true, true); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public String[] getBeanNamesForType(Class type, boolean includeNonSingletons, boolean allowEagerInit) { |
|
|
|
public String[] getBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) { |
|
|
|
|
|
|
|
if (type == null || !allowEagerInit) { |
|
|
|
|
|
|
|
return this.doGetBeanNamesForType(type, includeNonSingletons, allowEagerInit); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
Map<Class<?>, String[]> cache = includeNonSingletons ? |
|
|
|
|
|
|
|
this.nonSingletonBeanNamesByType : this.singletonBeanNamesByType; |
|
|
|
|
|
|
|
String[] resolvedBeanNames = cache.get(type); |
|
|
|
|
|
|
|
if (resolvedBeanNames != null) { |
|
|
|
|
|
|
|
return resolvedBeanNames; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
resolvedBeanNames = this.doGetBeanNamesForType(type, includeNonSingletons, allowEagerInit); |
|
|
|
|
|
|
|
cache.put(type, resolvedBeanNames); |
|
|
|
|
|
|
|
return resolvedBeanNames; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private String[] doGetBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) { |
|
|
|
List<String> result = new ArrayList<String>(); |
|
|
|
List<String> result = new ArrayList<String>(); |
|
|
|
|
|
|
|
|
|
|
|
// Check all bean definitions.
|
|
|
|
// Check all bean definitions.
|
|
|
|
@ -441,7 +465,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType) { |
|
|
|
public <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType) { |
|
|
|
A ann = null; |
|
|
|
A ann = null; |
|
|
|
Class beanType = getType(beanName); |
|
|
|
Class<?> beanType = getType(beanName); |
|
|
|
if (beanType != null) { |
|
|
|
if (beanType != null) { |
|
|
|
ann = AnnotationUtils.findAnnotation(beanType, annotationType); |
|
|
|
ann = AnnotationUtils.findAnnotation(beanType, annotationType); |
|
|
|
} |
|
|
|
} |
|
|
|
@ -564,18 +588,18 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto |
|
|
|
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); |
|
|
|
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); |
|
|
|
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { |
|
|
|
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { |
|
|
|
if (isFactoryBean(beanName)) { |
|
|
|
if (isFactoryBean(beanName)) { |
|
|
|
final FactoryBean factory = (FactoryBean) getBean(FACTORY_BEAN_PREFIX + beanName); |
|
|
|
final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName); |
|
|
|
boolean isEagerInit; |
|
|
|
boolean isEagerInit; |
|
|
|
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { |
|
|
|
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { |
|
|
|
isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() { |
|
|
|
isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() { |
|
|
|
public Boolean run() { |
|
|
|
public Boolean run() { |
|
|
|
return ((SmartFactoryBean) factory).isEagerInit(); |
|
|
|
return ((SmartFactoryBean<?>) factory).isEagerInit(); |
|
|
|
} |
|
|
|
} |
|
|
|
}, getAccessControlContext()); |
|
|
|
}, getAccessControlContext()); |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
else { |
|
|
|
isEagerInit = (factory instanceof SmartFactoryBean && |
|
|
|
isEagerInit = (factory instanceof SmartFactoryBean && |
|
|
|
((SmartFactoryBean) factory).isEagerInit()); |
|
|
|
((SmartFactoryBean<?>) factory).isEagerInit()); |
|
|
|
} |
|
|
|
} |
|
|
|
if (isEagerInit) { |
|
|
|
if (isEagerInit) { |
|
|
|
getBean(beanName); |
|
|
|
getBean(beanName); |
|
|
|
@ -669,6 +693,10 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto |
|
|
|
destroySingleton(beanName); |
|
|
|
destroySingleton(beanName); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Remove any assumptions about by-type mappings
|
|
|
|
|
|
|
|
this.singletonBeanNamesByType.clear(); |
|
|
|
|
|
|
|
this.nonSingletonBeanNamesByType.clear(); |
|
|
|
|
|
|
|
|
|
|
|
// Reset all bean definitions that have the given bean as parent (recursively).
|
|
|
|
// Reset all bean definitions that have the given bean as parent (recursively).
|
|
|
|
for (String bdName : this.beanDefinitionNames) { |
|
|
|
for (String bdName : this.beanDefinitionNames) { |
|
|
|
if (!beanName.equals(bdName)) { |
|
|
|
if (!beanName.equals(bdName)) { |
|
|
|
@ -723,7 +751,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (type.isArray()) { |
|
|
|
if (type.isArray()) { |
|
|
|
Class componentType = type.getComponentType(); |
|
|
|
Class<?> componentType = type.getComponentType(); |
|
|
|
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, componentType, descriptor); |
|
|
|
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, componentType, descriptor); |
|
|
|
if (matchingBeans.isEmpty()) { |
|
|
|
if (matchingBeans.isEmpty()) { |
|
|
|
if (descriptor.isRequired()) { |
|
|
|
if (descriptor.isRequired()) { |
|
|
|
@ -738,7 +766,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto |
|
|
|
return converter.convertIfNecessary(matchingBeans.values(), type); |
|
|
|
return converter.convertIfNecessary(matchingBeans.values(), type); |
|
|
|
} |
|
|
|
} |
|
|
|
else if (Collection.class.isAssignableFrom(type) && type.isInterface()) { |
|
|
|
else if (Collection.class.isAssignableFrom(type) && type.isInterface()) { |
|
|
|
Class elementType = descriptor.getCollectionType(); |
|
|
|
Class<?> elementType = descriptor.getCollectionType(); |
|
|
|
if (elementType == null) { |
|
|
|
if (elementType == null) { |
|
|
|
if (descriptor.isRequired()) { |
|
|
|
if (descriptor.isRequired()) { |
|
|
|
throw new FatalBeanException("No element type declared for collection [" + type.getName() + "]"); |
|
|
|
throw new FatalBeanException("No element type declared for collection [" + type.getName() + "]"); |
|
|
|
@ -759,7 +787,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto |
|
|
|
return converter.convertIfNecessary(matchingBeans.values(), type); |
|
|
|
return converter.convertIfNecessary(matchingBeans.values(), type); |
|
|
|
} |
|
|
|
} |
|
|
|
else if (Map.class.isAssignableFrom(type) && type.isInterface()) { |
|
|
|
else if (Map.class.isAssignableFrom(type) && type.isInterface()) { |
|
|
|
Class keyType = descriptor.getMapKeyType(); |
|
|
|
Class<?> keyType = descriptor.getMapKeyType(); |
|
|
|
if (keyType == null || !String.class.isAssignableFrom(keyType)) { |
|
|
|
if (keyType == null || !String.class.isAssignableFrom(keyType)) { |
|
|
|
if (descriptor.isRequired()) { |
|
|
|
if (descriptor.isRequired()) { |
|
|
|
throw new FatalBeanException("Key type [" + keyType + "] of map [" + type.getName() + |
|
|
|
throw new FatalBeanException("Key type [" + keyType + "] of map [" + type.getName() + |
|
|
|
@ -767,7 +795,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto |
|
|
|
} |
|
|
|
} |
|
|
|
return null; |
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
|
Class valueType = descriptor.getMapValueType(); |
|
|
|
Class<?> valueType = descriptor.getMapValueType(); |
|
|
|
if (valueType == null) { |
|
|
|
if (valueType == null) { |
|
|
|
if (descriptor.isRequired()) { |
|
|
|
if (descriptor.isRequired()) { |
|
|
|
throw new FatalBeanException("No value type declared for map [" + type.getName() + "]"); |
|
|
|
throw new FatalBeanException("No value type declared for map [" + type.getName() + "]"); |
|
|
|
@ -828,12 +856,12 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto |
|
|
|
* @see #autowireConstructor |
|
|
|
* @see #autowireConstructor |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
protected Map<String, Object> findAutowireCandidates( |
|
|
|
protected Map<String, Object> findAutowireCandidates( |
|
|
|
String beanName, Class requiredType, DependencyDescriptor descriptor) { |
|
|
|
String beanName, Class<?> requiredType, DependencyDescriptor descriptor) { |
|
|
|
|
|
|
|
|
|
|
|
String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors( |
|
|
|
String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors( |
|
|
|
this, requiredType, true, descriptor.isEager()); |
|
|
|
this, requiredType, true, descriptor.isEager()); |
|
|
|
Map<String, Object> result = new LinkedHashMap<String, Object>(candidateNames.length); |
|
|
|
Map<String, Object> result = new LinkedHashMap<String, Object>(candidateNames.length); |
|
|
|
for (Class autowiringType : this.resolvableDependencies.keySet()) { |
|
|
|
for (Class<?> autowiringType : this.resolvableDependencies.keySet()) { |
|
|
|
if (autowiringType.isAssignableFrom(requiredType)) { |
|
|
|
if (autowiringType.isAssignableFrom(requiredType)) { |
|
|
|
Object autowiringValue = this.resolvableDependencies.get(autowiringType); |
|
|
|
Object autowiringValue = this.resolvableDependencies.get(autowiringType); |
|
|
|
autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType); |
|
|
|
autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType); |
|
|
|
@ -918,7 +946,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto |
|
|
|
* Raise a NoSuchBeanDefinitionException for an unresolvable dependency. |
|
|
|
* Raise a NoSuchBeanDefinitionException for an unresolvable dependency. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
private void raiseNoSuchBeanDefinitionException( |
|
|
|
private void raiseNoSuchBeanDefinitionException( |
|
|
|
Class type, String dependencyDescription, DependencyDescriptor descriptor) |
|
|
|
Class<?> type, String dependencyDescription, DependencyDescriptor descriptor) |
|
|
|
throws NoSuchBeanDefinitionException { |
|
|
|
throws NoSuchBeanDefinitionException { |
|
|
|
|
|
|
|
|
|
|
|
throw new NoSuchBeanDefinitionException(type, dependencyDescription, |
|
|
|
throw new NoSuchBeanDefinitionException(type, dependencyDescription, |
|
|
|
@ -967,6 +995,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto |
|
|
|
* Minimal id reference to the factory. |
|
|
|
* Minimal id reference to the factory. |
|
|
|
* Resolved to the actual factory instance on deserialization. |
|
|
|
* Resolved to the actual factory instance on deserialization. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
@SuppressWarnings("serial") |
|
|
|
private static class SerializedBeanFactoryReference implements Serializable { |
|
|
|
private static class SerializedBeanFactoryReference implements Serializable { |
|
|
|
|
|
|
|
|
|
|
|
private final String id; |
|
|
|
private final String id; |
|
|
|
@ -976,7 +1005,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private Object readResolve() { |
|
|
|
private Object readResolve() { |
|
|
|
Reference ref = serializableFactories.get(this.id); |
|
|
|
Reference<?> ref = serializableFactories.get(this.id); |
|
|
|
if (ref == null) { |
|
|
|
if (ref == null) { |
|
|
|
throw new IllegalStateException( |
|
|
|
throw new IllegalStateException( |
|
|
|
"Cannot deserialize BeanFactory with id " + this.id + ": no factory registered for this id"); |
|
|
|
"Cannot deserialize BeanFactory with id " + this.id + ": no factory registered for this id"); |
|
|
|
@ -994,7 +1023,8 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto |
|
|
|
/** |
|
|
|
/** |
|
|
|
* Serializable ObjectFactory for lazy resolution of a dependency. |
|
|
|
* Serializable ObjectFactory for lazy resolution of a dependency. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
private class DependencyObjectFactory implements ObjectFactory, Serializable { |
|
|
|
@SuppressWarnings("serial") |
|
|
|
|
|
|
|
private class DependencyObjectFactory implements ObjectFactory<Object>, Serializable { |
|
|
|
|
|
|
|
|
|
|
|
private final DependencyDescriptor descriptor; |
|
|
|
private final DependencyDescriptor descriptor; |
|
|
|
|
|
|
|
|
|
|
|
@ -1015,7 +1045,8 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto |
|
|
|
/** |
|
|
|
/** |
|
|
|
* Serializable ObjectFactory for lazy resolution of a dependency. |
|
|
|
* Serializable ObjectFactory for lazy resolution of a dependency. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
private class DependencyProvider extends DependencyObjectFactory implements Provider { |
|
|
|
@SuppressWarnings("serial") |
|
|
|
|
|
|
|
private class DependencyProvider extends DependencyObjectFactory implements Provider<Object> { |
|
|
|
|
|
|
|
|
|
|
|
public DependencyProvider(DependencyDescriptor descriptor, String beanName) { |
|
|
|
public DependencyProvider(DependencyDescriptor descriptor, String beanName) { |
|
|
|
super(descriptor, beanName); |
|
|
|
super(descriptor, beanName); |
|
|
|
|