public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
       
       String id = ele.getAttribute(ID_ATTRIBUTE);//取得id属性
//取得name属性
       String nameAttr = ele.getAttribute(NAME_ATTRIBUTE); 
       List aliases = new ArrayList();//aliase属性 例如<alias name="fromName" alias="toName"/>
       if (StringUtils.hasLength(nameAttr)) {
//如果name属性存在,则把name的值分解,存储到aliases集合中
           String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, BEAN_NAME_DELIMITERS);
           aliases.addAll(Arrays.asList(nameArr));
       }
 
       String beanName = id;//默认id的值作为beanName
       if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {//如果id不存在,且aliases不为空,那么以aliases中的第一个作为beanName
           beanName = (String) aliases.remove(0);
           if (logger.isDebugEnabled()) {
              logger.debug("No XML 'id' specified - using '" + beanName +
                     "' as bean name and " + aliases + " as aliases");
           }
       }
 
       if (containingBean == null) {
           /*检查在一个文件中,beanName或者alias是否有重复的,如果有重复的报告错误,无重复,则把当前的beanName与alias记录到Set中*/
           checkNameUniqueness(beanName, aliases, ele);
       }
        
//对bean的详细解释,主要包括常见的class、parent、lazy-init、singleton等属性
       AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
       if (beanDefinition != null) {
           if (!StringUtils.hasText(beanName)) {
              try {
                  if (containingBean != null) {
                     beanName = BeanDefinitionReaderUtils.generateBeanName(
                            beanDefinition, this.readerContext.getRegistry(), true);
                  }
                  else {
/*容器生成beanName,其规则如下:
如果beanDefinition存在className,则以"className#编号"或者"className"作为beanName;
如果beanDefinition不存在className,且beanDefinition存在parentName,则以"parentName$child#编号"或者"parentName$child"作为beanName;
如果beanDefinition不存在className,且beanDefinition存在factorybeanName,则以"factoryBeanName$created#编号"或者"factoryBeanName$created"作为beanName;
注意,编号是通过查询容器是否包含beanName,然后累加获得的*/
                  beanName = this.readerContext.generateBeanName(beanDefinition);
String beanClassName = 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);
                  return null;
              }
           }
           String[] aliasesArray = StringUtils.toStringArray(aliases);
           //最后封装为BeanDefinitionHoler返回
           return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
       }
 
       return null;
}  
public AbstractBeanDefinition parseBeanDefinitionElement(
           Element ele, String beanName, BeanDefinition containingBean) {
       String className = null;//解释class属性
       if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
           className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
       }
       String parent = null;
       if (ele.hasAttribute(PARENT_ATTRIBUTE)) {//parent属性
           parent = ele.getAttribute(PARENT_ATTRIBUTE);
       }
 
       try {
//以bean的id作为参数封装到BeanEntry中;ParseState以Stack作为存储数据结构来存储Bean的解释状态
           this.parseState.push(new BeanEntry(beanName)); 
           
//创建了GenericBeanDefinition,并为其设置parent=='parent',beanClass=='class',beanClassName属性
           AbstractBeanDefinition bd = BeanDefinitionReaderUtils.createBeanDefinition(
                  parent, className, this.readerContext.getBeanClassLoader());
 
           if (ele.hasAttribute(SCOPE_ATTRIBUTE)) {//解释scope
              bd.setScope(ele.getAttribute(SCOPE_ATTRIBUTE));
              if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) {
                  error("Specify either 'scope' or 'singleton', not both", ele);
              }
           }
           else if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) {//singleton
    bd.setScope(TRUE_VALUE.equals(ele.getAttribute(SINGLETON_ATTRIBUTE)) ?
                     BeanDefinition.SCOPE_SINGLETON : BeanDefinition.SCOPE_PROTOTYPE);
           }
           else if (containingBean != null) {
                  bd.setScope(containingBean.getScope());
           }
 
           if (ele.hasAttribute(ABSTRACT_ATTRIBUTE)) {//解释abstract
              bd.setAbstract(TRUE_VALUE.equals(ele.getAttribute(ABSTRACT_ATTRIBUTE)));
           }
 
           String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE);//解释lazy-init
           if (DEFAULT_VALUE.equals(lazyInit) && bd.isSingleton()) {
              // Just apply default to singletons, as lazy-init has no meaning for prototypes.
              lazyInit = this.defaults.getLazyInit();
           }
           bd.setLazyInit(TRUE_VALUE.equals(lazyInit));
 
           String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE);//解释自动装配模式
           bd.setAutowireMode(getAutowireMode(autowire));
 
           String dependencyCheck = ele.getAttribute(DEPENDENCY_CHECK_ATTRIBUTE);
           bd.setDependencyCheck(getDependencyCheck(dependencyCheck));//解释依赖检查
 
           if (ele.hasAttribute(DEPENDS_ON_ATTRIBUTE)) {
              String dependsOn = ele.getAttribute(DEPENDS_ON_ATTRIBUTE);//解释depends-on
              bd.setDependsOn(StringUtils.tokenizeToStringArray(dependsOn, BEAN_NAME_DELIMITERS));
           }
 
           String autowireCandidate = ele.getAttribute(AUTOWIRE_CANDIDATE_ATTRIBUTE);
           if ("".equals(autowireCandidate) || DEFAULT_VALUE.equals(autowireCandidate)) {
              String candidatePattern = this.defaults.getAutowireCandidates();
              if (candidatePattern != null) {
                  String[] patterns = StringUtils.commaDelimitedListToStringArray(candidatePattern);
                  bd.setAutowireCandidate(PatternMatchUtils.simpleMatch(patterns, beanName));
              }
           }
           else {
              bd.setAutowireCandidate(TRUE_VALUE.equals(autowireCandidate));
           }
 
           if (ele.hasAttribute(PRIMARY_ATTRIBUTE)) {
              bd.setPrimary(TRUE_VALUE.equals(ele.getAttribute(PRIMARY_ATTRIBUTE)));
           }
 
           if (ele.hasAttribute(INIT_METHOD_ATTRIBUTE)) {
              String initMethodName = ele.getAttribute(INIT_METHOD_ATTRIBUTE);
              if (!"".equals(initMethodName)) {
                  bd.setInitMethodName(initMethodName);
              }
           }
           else {
              if (this.defaults.getInitMethod() != null) {
                  bd.setInitMethodName(this.defaults.getInitMethod());
                  bd.setEnforceInitMethod(false);
              }
           }
 
           if (ele.hasAttribute(DESTROY_METHOD_ATTRIBUTE)) {
              String destroyMethodName = ele.getAttribute(DESTROY_METHOD_ATTRIBUTE);
              if (!"".equals(destroyMethodName)) {
                  bd.setDestroyMethodName(destroyMethodName);
              }
           }
           else {
              if (this.defaults.getDestroyMethod() != null) {
                  bd.setDestroyMethodName(this.defaults.getDestroyMethod());
                  bd.setEnforceDestroyMethod(false);
              }
           }
 
           if (ele.hasAttribute(FACTORY_METHOD_ATTRIBUTE)) {//解释工厂方法属性
              bd.setFactoryMethodName(ele.getAttribute(FACTORY_METHOD_ATTRIBUTE));
           }
           if (ele.hasAttribute(FACTORY_BEAN_ATTRIBUTE)) {//解释工厂bean属性
              bd.setFactoryBeanName(ele.getAttribute(FACTORY_BEAN_ATTRIBUTE));
           }
 
           bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
 
           parseMetaElements(ele, bd);
           /**解释lookup-method(方法注入的一种),还记得吗,使用lookup-method能够覆盖bean标签指定的bean的抽象method(该method由method标签指定),主要针对singleton引用一个prototype的情形*/
           parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
           //解释replace-method(方法注入的一种)
           parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
 
           parseConstructorArgElements(ele, bd);
           /**这里把解释出来的属性值,ref[RuntimeBeanReference]、list[ManagedList]、set[ManagedSet]、map、properties,封装到PropertyValue,
       然后把PropertyValue加入到BeanDefinition*/
           parsePropertyElements(ele, bd);
           parseQualifierElements(ele, bd);
 
           bd.setResource(this.readerContext.getResource());
           bd.setSource(extractSource(ele));
 
           return bd;
}