defaultlistablebeanfactory.java
来自「spring framework 2.5.4源代码」· Java 代码 · 共 741 行 · 第 1/2 页
JAVA
741 行
* @param descriptor the descriptor of the dependency to resolve
* @return whether the bean should be considered as autowire candidate
*/
protected boolean isAutowireCandidate(String beanName, RootBeanDefinition mbd, DependencyDescriptor descriptor) {
resolveBeanClass(mbd, beanName);
return getAutowireCandidateResolver().isAutowireCandidate(
new BeanDefinitionHolder(mbd, beanName, getAliases(beanName)), descriptor);
}
public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
BeanDefinition bd = (BeanDefinition) this.beanDefinitionMap.get(beanName);
if (bd == null) {
if (this.logger.isTraceEnabled()) {
this.logger.trace("No bean named '" + beanName + "' found in " + this);
}
throw new NoSuchBeanDefinitionException(beanName);
}
return bd;
}
public void freezeConfiguration() {
this.configurationFrozen = true;
synchronized (this.beanDefinitionMap) {
this.frozenBeanDefinitionNames = StringUtils.toStringArray(this.beanDefinitionNames);
}
}
public boolean isConfigurationFrozen() {
return this.configurationFrozen;
}
/**
* Considers all beans as eligible for metdata caching
* if the factory's configuration has been marked as frozen.
* @see #freezeConfiguration()
*/
protected boolean isBeanEligibleForMetadataCaching(String beanName) {
return (this.configurationFrozen || super.isBeanEligibleForMetadataCaching(beanName));
}
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isInfoEnabled()) {
this.logger.info("Pre-instantiating singletons in " + this);
}
synchronized (this.beanDefinitionMap) {
for (Iterator it = this.beanDefinitionNames.iterator(); it.hasNext();) {
String beanName = (String) it.next();
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
FactoryBean factory = (FactoryBean) getBean(FACTORY_BEAN_PREFIX + beanName);
if (factory instanceof SmartFactoryBean && ((SmartFactoryBean) factory).isEagerInit()) {
getBean(beanName);
}
}
else {
getBean(beanName);
}
}
}
}
}
//---------------------------------------------------------------------
// Implementation of BeanDefinitionRegistry interface
//---------------------------------------------------------------------
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
Assert.hasText(beanName, "'beanName' must not be empty");
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
((AbstractBeanDefinition) beanDefinition).validate();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Validation of bean definition failed", ex);
}
}
synchronized (this.beanDefinitionMap) {
Object oldBeanDefinition = this.beanDefinitionMap.get(beanName);
if (oldBeanDefinition != null) {
if (!this.allowBeanDefinitionOverriding) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
"': There is already [" + oldBeanDefinition + "] bound.");
}
else {
if (this.logger.isInfoEnabled()) {
this.logger.info("Overriding bean definition for bean '" + beanName +
"': replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
}
}
}
else {
this.beanDefinitionNames.add(beanName);
this.frozenBeanDefinitionNames = null;
}
this.beanDefinitionMap.put(beanName, beanDefinition);
resetBeanDefinition(beanName);
}
}
public void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
Assert.hasText(beanName, "'beanName' must not be empty");
synchronized (this.beanDefinitionMap) {
BeanDefinition bd = (BeanDefinition) this.beanDefinitionMap.remove(beanName);
if (bd == null) {
if (this.logger.isTraceEnabled()) {
this.logger.trace("No bean named '" + beanName + "' found in " + this);
}
throw new NoSuchBeanDefinitionException(beanName);
}
this.beanDefinitionNames.remove(beanName);
this.frozenBeanDefinitionNames = null;
resetBeanDefinition(beanName);
}
}
/**
* Reset all bean definition caches for the given bean,
* including the caches of beans that are derived from it.
* @param beanName the name of the bean to reset
*/
protected void resetBeanDefinition(String beanName) {
// Remove the merged bean definition for the given bean, if already created.
clearMergedBeanDefinition(beanName);
// Remove corresponding bean from singleton cache, if any. Shouldn't usually
// be necessary, rather just meant for overriding a context's default beans
// (e.g. the default StaticMessageSource in a StaticApplicationContext).
synchronized (getSingletonMutex()) {
destroySingleton(beanName);
}
// Reset all bean definitions that have the given bean as parent
// (recursively).
for (Iterator it = this.beanDefinitionNames.iterator(); it.hasNext();) {
String bdName = (String) it.next();
if (!beanName.equals(bdName)) {
BeanDefinition bd = (BeanDefinition) this.beanDefinitionMap.get(bdName);
if (beanName.equals(bd.getParentName())) {
resetBeanDefinition(bdName);
}
}
}
}
/**
* Only allows alias overriding if bean definition overriding is allowed.
*/
protected boolean allowAliasOverriding() {
return this.allowBeanDefinitionOverriding;
}
//---------------------------------------------------------------------
// Implementation of superclass abstract methods
//---------------------------------------------------------------------
public Object resolveDependency(DependencyDescriptor descriptor, String beanName,
Set autowiredBeanNames, TypeConverter typeConverter) throws BeansException {
Class type = descriptor.getDependencyType();
if (type.isArray()) {
Class componentType = type.getComponentType();
Map matchingBeans = findAutowireCandidates(beanName, componentType, descriptor);
if (matchingBeans.isEmpty()) {
if (descriptor.isRequired()) {
raiseNoSuchBeanDefinitionException(componentType, "array of " + componentType.getName(), descriptor);
}
return null;
}
if (autowiredBeanNames != null) {
autowiredBeanNames.addAll(matchingBeans.keySet());
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
return converter.convertIfNecessary(matchingBeans.values(), type);
}
else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {
Class elementType = descriptor.getCollectionType();
if (elementType == null) {
if (descriptor.isRequired()) {
throw new FatalBeanException("No element type declared for collection [" + type.getName() + "]");
}
return null;
}
Map matchingBeans = findAutowireCandidates(beanName, elementType, descriptor);
if (matchingBeans.isEmpty()) {
if (descriptor.isRequired()) {
raiseNoSuchBeanDefinitionException(elementType, "collection of " + elementType.getName(), descriptor);
}
return null;
}
if (autowiredBeanNames != null) {
autowiredBeanNames.addAll(matchingBeans.keySet());
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
return converter.convertIfNecessary(matchingBeans.values(), type);
}
else if (Map.class.isAssignableFrom(type) && type.isInterface()) {
Class keyType = descriptor.getMapKeyType();
if (keyType == null || !String.class.isAssignableFrom(keyType)) {
if (descriptor.isRequired()) {
throw new FatalBeanException("Key type [" + keyType + "] of map [" + type.getName() +
"] must be assignable to [java.lang.String]");
}
return null;
}
Class valueType = descriptor.getMapValueType();
if (valueType == null) {
if (descriptor.isRequired()) {
throw new FatalBeanException("No value type declared for map [" + type.getName() + "]");
}
return null;
}
Map matchingBeans = findAutowireCandidates(beanName, valueType, descriptor);
if (matchingBeans.isEmpty()) {
if (descriptor.isRequired()) {
raiseNoSuchBeanDefinitionException(valueType, "map with value type " + valueType.getName(), descriptor);
}
return null;
}
if (autowiredBeanNames != null) {
autowiredBeanNames.addAll(matchingBeans.keySet());
}
return matchingBeans;
}
else {
Map matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
if (descriptor.isRequired()) {
throw new NoSuchBeanDefinitionException(type,
"Unsatisfied dependency of type [" + type + "]: expected at least 1 matching bean");
}
return null;
}
if (matchingBeans.size() > 1) {
String primaryBeanName = determinePrimaryCandidate(matchingBeans, type);
if (primaryBeanName == null) {
throw new NoSuchBeanDefinitionException(type,
"expected single matching bean but found " + matchingBeans.size() + ": " + matchingBeans.keySet());
}
if (autowiredBeanNames != null) {
autowiredBeanNames.add(primaryBeanName);
}
return matchingBeans.get(primaryBeanName);
}
// We have exactly one match.
Map.Entry entry = (Map.Entry) matchingBeans.entrySet().iterator().next();
if (autowiredBeanNames != null) {
autowiredBeanNames.add(entry.getKey());
}
return entry.getValue();
}
}
/**
* Find bean instances that match the required type.
* Called during autowiring for the specified bean.
* @param beanName the name of the bean that is about to be wired
* @param requiredType the actual type of bean to look for
* (may be an array component type or collection element type)
* @param descriptor the descriptor of the dependency to resolve
* @return a Map of candidate names and candidate instances that match
* the required type (never <code>null</code>)
* @throws BeansException in case of errors
* @see #autowireByType
* @see #autowireConstructor
*/
protected Map findAutowireCandidates(String beanName, Class requiredType, DependencyDescriptor descriptor) {
String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this, requiredType, true, descriptor.isEager());
Map result = new LinkedHashMap(candidateNames.length);
for (Iterator it = this.resolvableDependencies.keySet().iterator(); it.hasNext();) {
Class autowiringType = (Class) it.next();
if (autowiringType.isAssignableFrom(requiredType)) {
Object autowiringValue = this.resolvableDependencies.get(autowiringType);
if (autowiringValue instanceof ObjectFactory && !requiredType.isInstance(autowiringValue)) {
autowiringValue = ((ObjectFactory) autowiringValue).getObject();
}
if (requiredType.isInstance(autowiringValue)) {
result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
break;
}
}
}
for (int i = 0; i < candidateNames.length; i++) {
String candidateName = candidateNames[i];
if (!candidateName.equals(beanName) && isAutowireCandidate(candidateName, descriptor)) {
result.put(candidateName, getBean(candidateName));
}
}
return result;
}
/**
* Determine the primary autowire candidate in the given set of beans.
* @param candidateBeans a Map of candidate names and candidate instances
* that match the required type, as returned by {@link #findAutowireCandidates}
* @param type the required type
* @return the name of the primary candidate, or <code>null</code> if none found
*/
protected String determinePrimaryCandidate(Map candidateBeans, Class type) {
String primaryBeanName = null;
for (Iterator it = candidateBeans.entrySet().iterator(); it.hasNext();) {
Map.Entry entry = (Map.Entry) it.next();
String candidateBeanName = (String) entry.getKey();
if (isPrimary(candidateBeanName, entry.getValue())) {
if (primaryBeanName != null) {
throw new NoSuchBeanDefinitionException(type,
"more than one 'primary' bean found among candidates: " + candidateBeans.keySet());
}
primaryBeanName = candidateBeanName;
}
}
return primaryBeanName;
}
/**
* Return whether the bean definition for the given bean name has been
* marked as a primary bean.
* @param beanName the name of the bean
* @param beanInstance the corresponding bean instance
* @return whether the given bean qualifies as primary
*/
protected boolean isPrimary(String beanName, Object beanInstance) {
return ((containsBeanDefinition(beanName) && getMergedLocalBeanDefinition(beanName).isPrimary()) ||
this.resolvableDependencies.values().contains(beanInstance));
}
/**
* Raise a NoSuchBeanDefinitionException for an unresolvable dependency.
*/
private void raiseNoSuchBeanDefinitionException(
Class type, String dependencyDescription, DependencyDescriptor descriptor)
throws NoSuchBeanDefinitionException {
throw new NoSuchBeanDefinitionException(type, dependencyDescription,
"expected at least 1 bean which qualifies as autowire candidate for this dependency. " +
"Dependency annotations: " + ObjectUtils.nullSafeToString(descriptor.getAnnotations()));
}
public String toString() {
StringBuffer sb = new StringBuffer(ObjectUtils.identityToString(this));
sb.append(": defining beans [");
sb.append(StringUtils.arrayToCommaDelimitedString(getBeanDefinitionNames()));
sb.append("]; ");
BeanFactory parent = getParentBeanFactory();
if (parent == null) {
sb.append("root of factory hierarchy");
}
else {
sb.append("parent: " + ObjectUtils.identityToString(parent));
}
return sb.toString();
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?