protectedvoiddoRegisterBeanDefinitions(Element root){// Any nested <beans> elements will cause recursion in this method. In// order to propagate and preserve <beans> default-* attributes correctly,// keep track of the current (parent) delegate, which may be null. Create// the new (child) delegate with a reference to the parent for fallback purposes,// then ultimately reset this.delegate back to its original (parent) reference.// this behavior emulates a stack of delegates without actually necessitating one.// BeanDefintion解析委托类BeanDefinitionParserDelegate parent =this.delegate;this.delegate =createDelegate(getReaderContext(), root, parent);// 判断这个根节点是否是默认的命名空间,// 底层就是判断这个根节点的nameSpaceUrl=="http://www./schema/beans"if(this.delegate.isDefaultNamespace(root)){// 获取这个profile属性的值,表示剖面,用于设置环境String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);if(StringUtils.hasText(profileSpec)){// 根据分隔符换换成数组String[] specifiedProfiles =StringUtils.tokenizeToStringArray(
profileSpec,BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);// We cannot use Profiles.of(...) since profile expressions are not supported// in XML config. See SPR-12458 for details.// 判断这个切面是否是激活的环境,如果不是直接返回,表示这个配置文件不是当前运行环境的配置文件if(!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)){if(logger.isDebugEnabled()){
logger.debug("Skipped XML bean definition file due to specified profiles ["+ profileSpec +"] not matching: "+getReaderContext().getResource());}return;}}}// 在解析xml之前做的准备工作,其实什么也没做preProcessXml(root);// 调用这个方法,解析parseBeanDefinitions(root,this.delegate);// 后续处理的postProcessXml(root);this.delegate = parent;}
publicBeanDefinitionHolderparseBeanDefinitionElement(Element ele,@NullableBeanDefinition containingBean){// 获取<Bean>元素中的id属性值String id = ele.getAttribute(ID_ATTRIBUTE);// 获取<Bean>元素中的name属性值// <bean class="study.spring.bean.Bean" id="bean1" name="firstBean 1stBean"></bean>String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);List<String> aliases =newArrayList<>();// 将<Bean>元素中的所有name属性值存放到别名中if(StringUtils.hasLength(nameAttr)){String[] nameArr =StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
aliases.addAll(Arrays.asList(nameArr));}String beanName = id;if(!StringUtils.hasText(beanName)&&!aliases.isEmpty()){
beanName = aliases.remove(0);if(logger.isTraceEnabled()){
logger.trace("No XML 'id' specified - using '"+ beanName +"' as bean name and "+ aliases +" as aliases");}}// 元素中是否包含嵌套<Bean>元素if(containingBean ==null){// 检查<Bean>元素所配置的id、name或者别名是否重复checkNameUniqueness(beanName, aliases, ele);}// 对 <bean> 标签的其他属性进行解析AbstractBeanDefinition beanDefinition =parseBeanDefinitionElement(ele, beanName, containingBean);// 生要给BeanDefinition起名字if(beanDefinition !=null){if(!StringUtils.hasText(beanName)){try{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.String beanClassName = beanDefinition.getBeanClassName();if(beanClassName !=null&&
beanName.startsWith(beanClassName)&& beanName.length()> beanClassName.length()&&!this.readerContext.getRegistry().isBeanNameInUse(beanClassName)){
aliases.add(beanClassName);}}if(logger.isTraceEnabled()){
logger.trace("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);}returnnull;}