StringbeanName= id; if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) { beanName = aliases.remove(0); if (logger.isDebugEnabled()) { logger.debug("No XML 'id' specified - using '" + beanName + "' as bean name and " + aliases + " as aliases"); } }
if (containingBean == null) { checkNameUniqueness(beanName, aliases, ele); }
AbstractBeanDefinitionbeanDefinition= parseBeanDefinitionElement(ele, beanName, containingBean); if (beanDefinition != null) { if (!StringUtils.hasText(beanName)) { try { // 如果不存在beanName,那么根据Spring中提供的命名规则为当前bean生成beanName if (containingBean != null) { beanName = BeanDefinitionReaderUtils.generateBeanName( beanDefinition, this.readerContext.getRegistry(), true); } else { beanName = this.readerContext.generateBeanName(beanDefinition); // Register an alias for the plain bean class name, if still possible, // if the generator returned the class name plus a suffix. // This is expected for Spring 1.2/2.0 backwards compatibility. StringbeanClassName= beanDefinition.getBeanClassName(); if (beanClassName != null && beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() && !this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) { aliases.add(beanClassName); } } if (logger.isDebugEnabled()) { logger.debug("Neither XML 'id' nor 'name' specified - " + "using generated bean name [" + beanName + "]"); } } catch (Exception ex) { error(ex.getMessage(), ele); returnnull; } } String[] aliasesArray = StringUtils.toStringArray(aliases); returnnewBeanDefinitionHolder(beanDefinition, beanName, aliasesArray); }
Spring 通过BeanDefinition将配置文件中的**配置信息转换为容器的内部表示,并将这些BeanDefiniton注册到BeanDefinitonRegistry中。Spring容器的BeanDefinitionRegistry就像是Spring配置信息的内存数据库,主要是以map的形式保存,后续操作直接从BeanDefinition- Registry中读取配置信息**。
// 解析singleton属性 if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) { error("Old 1.x 'singleton' attribute in use - upgrade to 'scope' declaration", ele); } // 解析scope属性 elseif (ele.hasAttribute(SCOPE_ATTRIBUTE)) { bd.setScope(ele.getAttribute(SCOPE_ATTRIBUTE)); } elseif (containingBean != null) { // Take default from containing bean in case of an inner bean definition. bd.setScope(containingBean.getScope()); }
// 解析abstract属性 if (ele.hasAttribute(ABSTRACT_ATTRIBUTE)) { bd.setAbstract(TRUE_VALUE.equals(ele.getAttribute(ABSTRACT_ATTRIBUTE))); }
/** * Constant for the default scope name: {@code ""}, equivalent to singleton * status unless overridden from a parent bean definition (if applicable). */ publicstaticfinalStringSCOPE_DEFAULT="";
/** * Constant that indicates no external autowiring at all. * @see #setAutowireMode */ publicstaticfinalintAUTOWIRE_NO= AutowireCapableBeanFactory.AUTOWIRE_NO;
/** * Constant that indicates autowiring bean properties by name. * @see #setAutowireMode */ publicstaticfinalintAUTOWIRE_BY_NAME= AutowireCapableBeanFactory.AUTOWIRE_BY_NAME;
/** * Constant that indicates autowiring bean properties by type. * @see #setAutowireMode */ publicstaticfinalintAUTOWIRE_BY_TYPE= AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE;
/** * Constant that indicates autowiring a constructor. * @see #setAutowireMode */ publicstaticfinalintAUTOWIRE_CONSTRUCTOR= AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR;
/** * Constant that indicates determining an appropriate autowire strategy * through introspection of the bean class. * @see #setAutowireMode * @deprecated as of Spring 3.0: If you are using mixed autowiring strategies, * use annotation-based autowiring for clearer demarcation of autowiring needs. */ @Deprecated publicstaticfinalintAUTOWIRE_AUTODETECT= AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT;
/** * Constant that indicates no dependency check at all. * @see #setDependencyCheck */ publicstaticfinalintDEPENDENCY_CHECK_NONE=0;
/** * Constant that indicates dependency checking for object references. * @see #setDependencyCheck */ publicstaticfinalintDEPENDENCY_CHECK_OBJECTS=1;
/** * Constant that indicates dependency checking for "simple" properties. * @see #setDependencyCheck * @see org.springframework.beans.BeanUtils#isSimpleProperty */ publicstaticfinalintDEPENDENCY_CHECK_SIMPLE=2;
/** * Constant that indicates dependency checking for all properties * (object references as well as "simple" properties). * @see #setDependencyCheck */ publicstaticfinalintDEPENDENCY_CHECK_ALL=3;
/** * Constant that indicates the container should attempt to infer the * {@link #setDestroyMethodName destroy method name} for a bean as opposed to * explicit specification of a method name. The value {@value} is specifically * designed to include characters otherwise illegal in a method name, ensuring * no possibility of collisions with legitimately named methods having the same * name. * <p>Currently, the method names detected during destroy method inference * are "close" and "shutdown", if present on the specific bean class. */ publicstaticfinalStringINFER_METHOD="(inferred)";
@Override publicvoidregisterAlias(String name, String alias) { Assert.hasText(name, "'name' must not be empty"); Assert.hasText(alias, "'alias' must not be empty"); synchronized (this.aliasMap) { if (alias.equals(name)) { this.aliasMap.remove(alias); if (logger.isDebugEnabled()) { logger.debug("Alias definition '" + alias + "' ignored since it points to same name"); } } else { StringregisteredName=this.aliasMap.get(alias); if (registeredName != null) { if (registeredName.equals(name)) { // An existing alias - no need to re-register return; } if (!allowAliasOverriding()) { thrownewIllegalStateException("Cannot define alias '" + alias + "' for name '" + name + "': It is already registered for name '" + registeredName + "'."); } if (logger.isInfoEnabled()) { logger.info("Overriding alias '" + alias + "' definition for registered name '" + registeredName + "' with new target name '" + name + "'"); } } checkForAliasCircle(name, alias); this.aliasMap.put(alias, name); if (logger.isDebugEnabled()) { logger.debug("Alias definition '" + alias + "' registered for name '" + name + "'"); } } } }