Let’s learn SF framework series 5.7-spring-Beans-BeanDefinition analysis together

Developers define application beans according to metadata rules. Understanding how SF is parsed into BeanDefiniton according to the definition can help to deeply understand the framework implementation. The parsing process is as follows:

Resource loading

The actual process of loading the bean's metadata configuration from the resource file is as follows: the
Insert image description here
actual loading of the bean definition from the specified XML file starts with XmlBeanDefinitionReader.doLoadBeanDefinitions.

parse

Parsing is two major steps:
1. Parse the resource file content into a DOM document through a SAX parser.
2. Generate BeanDefinition
source code (XmlBeanDefinitionReader.doLoadBeanDefinitions) from the DOM document:

	protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
			throws BeanDefinitionStoreException {
    
    

		try {
    
    
			//将资源解析成Document
			Document doc = doLoadDocument(inputSource, resource);
			//基于Document生成BeanDefinition
			int count = registerBeanDefinitions(doc, resource);
			if (logger.isDebugEnabled()) {
    
    
				logger.debug("Loaded " + count + " bean definitions from " + resource);
			}
			return count;
		}
		catch (BeanDefinitionStoreException ex) {
    
    
			throw ex;
		}
		catch (SAXParseException ex) {
    
    
			throw new XmlBeanDefinitionStoreException(resource.getDescription(),
					"Line " + ex.getLineNumber() + " in XML document from " + resource + " is invalid", ex);
		}
		catch (SAXException ex) {
    
    
			throw new XmlBeanDefinitionStoreException(resource.getDescription(),
					"XML document from " + resource + " is invalid", ex);
		}
		catch (ParserConfigurationException ex) {
    
    
			throw new BeanDefinitionStoreException(resource.getDescription(),
					"Parser configuration exception parsing XML from " + resource, ex);
		}
		catch (IOException ex) {
    
    
			throw new BeanDefinitionStoreException(resource.getDescription(),
					"IOException parsing XML document from " + resource, ex);
		}
		catch (Throwable ex) {
    
    
			throw new BeanDefinitionStoreException(resource.getDescription(),
					"Unexpected exception parsing XML document from " + resource, ex);
		}
	}

Resource files to Document

The implementation of Spring is relatively complex. The basic relationship diagram is as follows:
Insert image description here
It mainly uses SAX to parse XML format metadata into DOM documents. It has little to do with the purpose of Spring itself. There is no need to track the code in detail. Interested students can learn and understand it by themselves.

Document to BeanDefinition

Main process

Insert image description here

XmlBeanDefinitionReader.registerBeanDefinitions(Document doc, Resource resource)

	public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
    
    
		//生成DOM解析器(负责生成BeanDefinition)
		BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
		//返回已经注册在BeanFactory中的beanDefinitions数量(支持多个元数据配置文件)
		int countBefore = getRegistry().getBeanDefinitionCount();
		//生成BeanDefinition
		documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
		//返回本次beanDefinitions数量(BeanFactory现有数量-生成前记录的数量)
		return getRegistry().getBeanDefinitionCount() - countBefore;
	}

BeanDefinitionDocumentReader.registerBeanDefinitions(Document doc, XmlReaderContext readerContext)

It's obvious at a glance.

	@Override
	public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
    
    
		this.readerContext = readerContext;
		doRegisterBeanDefinitions(doc.getDocumentElement());
	}

BeanDefinitionDocumentReader.doRegisterBeanDefinitions(Element root)

Begin parsing from the bean root element ( ).

	//不理解怎么成deprecation
	@SuppressWarnings("deprecation")  // for Environment.acceptsProfiles(String...)
	protected void doRegisterBeanDefinitions(Element root) {
    
    
    	//保存BeanDefinitionParser代理
    	BeanDefinitionParserDelegate parent = this.delegate;
    	
    	//生成当前用的BeanDefinitionParser代理,初始化一些默认值
		this.delegate = createDelegate(getReaderContext(), root, parent);
		//默认命名空间是"http://www.springframework.org/schema/beans"
		if (this.delegate.isDefaultNamespace(root)) {
    
    
			//xml文件中沒有使用到"profile",有的话需要加载profile相关值 注1
			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);
		//生成BeanDefinition,并注册到BeanFactory
		parseBeanDefinitions(root, this.delegate);
		//xml预处理(空实现)
		postProcessXml(root);

		//恢复BeanDefinitionParser代理
		this.delegate = parent;
	}

Note 1 What is profile, refer to: Learn SF Framework Series 6.2 together - module core-Environment

BeanDefinitionDocumentReader.parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate)

Generate BeanDefinition and register it to BeanFactory.

	protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
    
    
		//根节点是默认命名空间(http://www.springframework.org/schema/beans)解析 注1
		if (delegate.isDefaultNamespace(root)) {
    
    
			//获取根节点下所有子节点
			NodeList nl = root.getChildNodes();
			//逐一解析每个子节点
			for (int i = 0; i < nl.getLength(); i++) {
    
    
				Node node = nl.item(i);
				if (node instanceof Element ele) {
    
    
					//每个子节点按命名空间对应解析器进行解析
					if (delegate.isDefaultNamespace(ele)) {
    
    
						parseDefaultElement(ele, delegate);
					}
					else {
    
    
						delegate.parseCustomElement(ele);
					}
				}
			}
		}
		else {
    
    
			//非默认命名空间解析
			delegate.parseCustomElement(root);
		}
	}

Note 1: The understanding of namespace is as follows. One namespace corresponds to one parsing processor:
If annotation configuration is enabled, the following line needs to be added to the spring configuration file applicationContext.xml:
<context:annotation-config />
means the label annotation -config belongs to the namespace context. context corresponds to a parsing processor. When parsing, you need to first obtain the parsing processor corresponding to the context. The parsing processor will initialize some parsers, and one parser corresponds to a tag.
Trace down based on how the default namespace is resolved.

BeanDefinitionDocumentReader.parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate)

Element resolution for the default namespace.

private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
    
    
    
    //<import>标签进入这个方法
    if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
    
    
        importBeanDefinitionResource(ele);
    }
    
    //<alias>标签进入这个方法
    else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
    
    
        processAliasRegistration(ele);
    }
    
    //<bean>标签进入这个方法
    else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
    
    
        //进入这个方法
        processBeanDefinition(ele, delegate);
    }
    
    //嵌套标签进入这个方法
    else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
    
    
        // 嵌套标签从doRegisterBeanDefinitions递归开始
        doRegisterBeanDefinitions(ele);
    }
}

Trace downward based on generated beans.

BeanDefinitionDocumentReader.processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate)

Parse the bean element into a BeanDefinition and register it in the BeanFactory.

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
    
    
   
    //把元素解析成BeanDefinition
    BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
    if (bdHolder != null) {
    
      
        //装饰beanDefinition
        bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
        try {
    
    
            //注册BeanDefinition到工厂中
            BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
        }
        catch (BeanDefinitionStoreException ex) {
    
    
            getReaderContext().error("Failed to register bean definition with name '" +
                                     bdHolder.getBeanName() + "'", ele, ex);
        }
        
        // 发送组件(bean)注册事件
        getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
    }
}

BeanDefinitionParserDelegate.parseBeanDefinitionElement(Element ele)

//Parse the elements into BeanDefinition

public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {
    
    
    return parseBeanDefinitionElement(ele, null);
}
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
    
      
    //获取元素id
    String id = ele.getAttribute(ID_ATTRIBUTE);
    
    //获取元素name
    String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);

    //记录元素alias
    List<String> aliases = new ArrayList<String>();
    
    /* id、name、alias关系处理 注1 */
    //name解析
    if (StringUtils.hasLength(nameAttr)) {
    
    
        //name属性对应的name值如果有分隔符MULTI_VALUE_ATTRIBUTE_DELIMITERS,那么切分成数组
        String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
        //所有name都是别名
        aliases.addAll(Arrays.asList(nameArr));
    }
    //指定了id就用id值作为bean名称
    String beanName = id;
    //如果没有id,但是指定了name,就用name值作为bean名称
    if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
    
    
        //拿第一个name值作为bean名称,其余的还是别名
        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) {
    
            
        //检查bean名称和别名是否已经被使用了,如果用了就报错
        checkNameUniqueness(beanName, aliases, ele);
    }
    
    //解析beanDefinition本身
    AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
    if (beanDefinition != null) {
    
           
        //如果没有定义id、name、alias,自动生成beanName
        if (!StringUtils.hasText(beanName)) {
    
    
            try {
    
    
                //有containingBean
                if (containingBean != null) {
    
    
                    beanName = BeanDefinitionReaderUtils.generateBeanName(
                        beanDefinition, this.readerContext.getRegistry(), true);
                }
                else {
    
    
                    //无containingBean,用容器生成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)) {
    
    
                        
                        //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);
        //组装成完整beanDefinition返回
        return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
    }

    return null;
}

Note 1: To understand the id, name, and alias relationships of beans, refer to: Learn SF Framework Series 5.1-Module Beans-bean Overview

BeanDefinitionParserDelegate.parseBeanDefinitionElement(Element ele, String beanName, @Nullable BeanDefinition containingBean)

It does not pay attention to the name and alias of the bean, but only parses the BeanDefinition itself.

public AbstractBeanDefinition parseBeanDefinitionElement(
    Element ele, String beanName, BeanDefinition containingBean) {
    
    
    //解析的beanName进栈(主要考虑元素ele可能还嵌套有子元素,则后续放入子元素,到时子元素先弹出
    this.parseState.push(new BeanEntry(beanName));

    String className = null;
    if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
    
    
        //如果有指定class属性,则拿到class属性值
        className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
    }
    String parent = null;
    if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
    
               
        //如果有指定parent属性,则拿到parent属性值
        parent = ele.getAttribute(PARENT_ATTRIBUTE);
    }

    try {
    
           
        //创建BeanDefinition
        AbstractBeanDefinition bd = createBeanDefinition(className, parent);
        
        //设置BeanDefinition属性
        parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
        
        //如果有description子元素,设置到BeanDefinition中
        bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
        
        //如果有Meta子元素,获取key和value属性,设置到BeanDefinition中
        parseMetaElements(ele, bd);
        
        //如果有lookup-method子元素,获取name和bean属性,设置到BeanDefinition中
        parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
        
        //如果有replaced-method子元素,设置BeanDefinition 
        parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
        
        //如果有constructor-arg子元素,设置BeanDefinition的构造方式
        parseConstructorArgElements(ele, bd);
        
        //解析bean的Property的属性设置到BeanDefinition中
        parsePropertyElements(ele, bd);
        
        //子元素qualifier处理
        parseQualifierElements(ele, bd);
        
        //设置定义来源
        bd.setResource(this.readerContext.getResource());
        
        //元素有Source
        bd.setSource(extractSource(ele));

        return bd;
    }
    catch (ClassNotFoundException ex) {
    
    
        error("Bean class [" + className + "] not found", ele, ex);
    }
    catch (NoClassDefFoundError err) {
    
    
        error("Class that bean class [" + className + "] depends on not found", ele, err);
    }
    catch (Throwable ex) {
    
    
        error("Unexpected failure during bean definition parsing", ele, ex);
    }
    finally {
    
    
        //解析完成出栈
        this.parseState.pop();
    }

    return null;
}

BeanDefinitionParserDelegate.createBeanDefinition(@Nullable String className, @Nullable String parentName)

Create BeanDefinition and set properties: parentName and beanClassName

protected AbstractBeanDefinition createBeanDefinition(String className, String parentName)
    throws ClassNotFoundException {
    
    
    return BeanDefinitionReaderUtils.createBeanDefinition(
        parentName, className, this.readerContext.getBeanClassLoader());
}

/**
* 此方法是BeanDefinitionReaderUtils的静态方法
*/
public static AbstractBeanDefinition createBeanDefinition(
    String parentName, String className, ClassLoader classLoader) throws ClassNotFoundException {
    
    
	//new通用BeanDefinition
    GenericBeanDefinition bd = new GenericBeanDefinition();
    bd.setParentName(parentName);
    if (className != null) {
    
    
        if (classLoader != null) {
    
    
            //有classLoader,就导入Class
            bd.setBeanClass(ClassUtils.forName(className, classLoader));
        }
        else {
    
              
            //无classLoader,只设置BeanClassName
            bd.setBeanClassName(className);
        }
    }
    return bd;
}

BeanDefinitionParserDelegate.parseBeanDefinitionAttributes(Element ele, String beanName, @Nullable BeanDefinition containingBean, AbstractBeanDefinition bd)

Parse bean definition settings into BeanDefinition properties

public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName,
                                                            BeanDefinition containingBean, AbstractBeanDefinition bd) {
    
    
    
    //有singleton属性报错(新的用scope代替)
    if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) {
    
    
        error("Old 1.x 'singleton' attribute in use - upgrade to 'scope' declaration", ele);
    }    
    //如果有scope配置
    else if (ele.hasAttribute(SCOPE_ATTRIBUTE)) {
    
    
        bd.setScope(ele.getAttribute(SCOPE_ATTRIBUTE));
    }
    else if (containingBean != null) {
    
    
        // 按containingBean的Scope设置
        bd.setScope(containingBean.getScope());
    }
    
    //是否有abstract属性
    if (ele.hasAttribute(ABSTRACT_ATTRIBUTE)) {
    
    
        bd.setAbstract(TRUE_VALUE.equals(ele.getAttribute(ABSTRACT_ATTRIBUTE)));
    }

    //设置lazyInit属性(如果没有设置则为默认值)
    String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE);
    if (DEFAULT_VALUE.equals(lazyInit)) {
    
    
        lazyInit = this.defaults.getLazyInit();
    }
    bd.setLazyInit(TRUE_VALUE.equals(lazyInit)); //非TRUE_VALUE则为false
    
    //设置autowire属性
    String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE);
    bd.setAutowireMode(getAutowireMode(autowire));
    
    //设置依赖检查属性
    String dependencyCheck = ele.getAttribute(DEPENDENCY_CHECK_ATTRIBUTE);
    bd.setDependencyCheck(getDependencyCheck(dependencyCheck));
    
    //设置depends-on属性
    if (ele.hasAttribute(DEPENDS_ON_ATTRIBUTE)) {
    
    
        String dependsOn = ele.getAttribute(DEPENDS_ON_ATTRIBUTE);
        bd.setDependsOn(StringUtils.tokenizeToStringArray(dependsOn, MULTI_VALUE_ATTRIBUTE_DELIMITERS));
    }
    
    //设置autowire-candidate属性
    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));
    }
    
    //设置primary属性
    if (ele.hasAttribute(PRIMARY_ATTRIBUTE)) {
    
    
        bd.setPrimary(TRUE_VALUE.equals(ele.getAttribute(PRIMARY_ATTRIBUTE)));
    }
    
    //设置init-method属性
    if (ele.hasAttribute(INIT_METHOD_ATTRIBUTE)) {
    
    
        String initMethodName = ele.getAttribute(INIT_METHOD_ATTRIBUTE);
        if (!"".equals(initMethodName)) {
    
    
            bd.setInitMethodName(initMethodName);
        }
    }
    else {
    
    
        //没有init-method属性,设置默认InitMethod
        if (this.defaults.getInitMethod() != null) {
    
    
            bd.setInitMethodName(this.defaults.getInitMethod());
            bd.setEnforceInitMethod(false);
        }
    }
    
    //设置destroy-method属性
    if (ele.hasAttribute(DESTROY_METHOD_ATTRIBUTE)) {
    
    
        String destroyMethodName = ele.getAttribute(DESTROY_METHOD_ATTRIBUTE);
        bd.setDestroyMethodName(destroyMethodName);
    }
    else {
    
    
        //没有destroy-method属性,设置默认DestroyMethod
        if (this.defaults.getDestroyMethod() != null) {
    
    
            bd.setDestroyMethodName(this.defaults.getDestroyMethod());
            bd.setEnforceDestroyMethod(false);
        }
    }
    
    //设置factory-method属性
    if (ele.hasAttribute(FACTORY_METHOD_ATTRIBUTE)) {
    
    
        bd.setFactoryMethodName(ele.getAttribute(FACTORY_METHOD_ATTRIBUTE));
    }
    
    //设置factory-bean属性
    if (ele.hasAttribute(FACTORY_BEAN_ATTRIBUTE)) {
    
    
        bd.setFactoryBeanName(ele.getAttribute(FACTORY_BEAN_ATTRIBUTE));
    }

    return bd;
}

BeanDefinitionParserDelegate.parsePropertyElements(Element beanEle, BeanDefinition bd)

Parse the property value of the bean.

public void parsePropertyElements(Element beanEle, BeanDefinition bd) {
    
    
    NodeList nl = beanEle.getChildNodes();
    for (int i = 0; i < nl.getLength(); i++) {
    
    
        Node node = nl.item(i);
        if (isCandidateElement(node) && nodeNameEquals(node, PROPERTY_ELEMENT)) {
    
    
            //元素为PROPERTY_ELEMENT才处理
            parsePropertyElement((Element) node, bd);
        }
    }
}

public void parsePropertyElement(Element ele, BeanDefinition bd) {
    
    
    //property标签的name属性
    String propertyName = ele.getAttribute(NAME_ATTRIBUTE);
    if (!StringUtils.hasLength(propertyName)) {
    
    
        error("Tag 'property' must have a 'name' attribute", ele);
        return;
    }
    
    //解析property元素进栈
    this.parseState.push(new PropertyEntry(propertyName));
    
    try {
    
    
        //propertyName不能重复name
        if (bd.getPropertyValues().contains(propertyName)) {
    
    
            error("Multiple 'property' definitions for property '" + propertyName + "'", ele);
            return;
        }
        
        //具体解析property元素属性
        Object val = parsePropertyValue(ele, bd, propertyName);
        
        //生成PropertyValue(propertyName:value)
        PropertyValue pv = new PropertyValue(propertyName, val);
        
        //ele有meta子元素,获取meta的key和value属性,设置到PropertyValue中
        parseMetaElements(ele, pv);
        
        pv.setSource(extractSource(ele));
        
        //将PropertyValue添加到BeanDefinition中
        bd.getPropertyValues().addPropertyValue(pv);
    }
    finally {
    
          
        //解析property元素出栈
        this.parseState.pop();
    }
}

public Object parsePropertyValue(Element ele, BeanDefinition bd, String propertyName) {
    
    
   
    //如果propertyName为null,则是constructor-arg元素
    String elementName = (propertyName != null) ?
        "<property> element for property '" + propertyName + "'" :
    "<constructor-arg> element";
    
    //Property下面都应该只有一个子标签: ref, value, list等.
    NodeList nl = ele.getChildNodes();
    Element subElement = null;
    for (int i = 0; i < nl.getLength(); i++) {
    
    
        Node node = nl.item(i);
        if (node instanceof Element && !nodeNameEquals(node, DESCRIPTION_ELEMENT) &&
            !nodeNameEquals(node, META_ELEMENT)) {
    
    
            //除开description和meta标签,子标签最多只能有一个
            if (subElement != null) {
    
    
                error(elementName + " must not contain more than one sub-element", ele);
            }
            else {
    
    
                subElement = (Element) node;
            }
        }
    }
    
    //元素属性类型ref、value
    boolean hasRefAttribute = ele.hasAttribute(REF_ATTRIBUTE);
    boolean hasValueAttribute = ele.hasAttribute(VALUE_ATTRIBUTE);
    
    //value和ref属性不能同时存在;如果有子元素,则value和ref都不能存在,否则报错
    if ((hasRefAttribute && hasValueAttribute) ||
        ((hasRefAttribute || hasValueAttribute) && subElement != null)) {
    
    
        error(elementName +
              " is only allowed to contain either 'ref' attribute OR 'value' attribute OR sub-element", ele);
    }
    
    //元素属性是ref的情况
    if (hasRefAttribute) {
    
    
        String refName = ele.getAttribute(REF_ATTRIBUTE);
        if (!StringUtils.hasText(refName)) {
    
    
            error(elementName + " contains empty 'ref' attribute", ele);
        }
        //RuntimeBeanReference是ref的不可变占位符类,实际在运行时解析为真正的bean引用实例
        RuntimeBeanReference ref = new RuntimeBeanReference(refName);
        ref.setSource(extractSource(ele));
        return ref;
    }
    //元素属性是value的情况
    else if (hasValueAttribute) {
    
    
    	//valueHolder存储String值和目标类型。实际的转换将由BeanFactory执行
        TypedStringValue valueHolder = new TypedStringValue(ele.getAttribute(VALUE_ATTRIBUTE));
        valueHolder.setSource(extractSource(ele));
        return valueHolder;
    }
    else if (subElement != null) {
    
    
	    //子元素处理
        return parsePropertySubElement(subElement, bd);
    }
    else {
    
    
        //没指定ref或者value或者子元素,返回null
        error(elementName + " must specify a ref or value", ele);
        return null;
    }
}

//过渡方法
public Object parsePropertySubElement(Element ele, BeanDefinition bd) {
    
    
    return parsePropertySubElement(ele, bd, null);
}

//解析property或者constructor-arg标签的子标签,可能为value, ref或者集合
public Object parsePropertySubElement(Element ele, BeanDefinition bd, String defaultValueType) {
    
    
    //如果ele不属于默认命名空间
    if (!isDefaultNamespace(ele)) {
    
    
        return parseNestedCustomElement(ele, bd);
    }
    else if (nodeNameEquals(ele, BEAN_ELEMENT)) {
    
    
        //如果ele是bean类型,嵌套bean处理
        BeanDefinitionHolder nestedBd = parseBeanDefinitionElement(ele, bd);
        if (nestedBd != null) {
    
    
            nestedBd = decorateBeanDefinitionIfRequired(ele, nestedBd, bd);
        }
        return nestedBd;
    }
    else if (nodeNameEquals(ele, REF_ELEMENT)) {
    
    
	    //如果ele是ref元素类型
        String refName = ele.getAttribute(BEAN_REF_ATTRIBUTE);
        boolean toParent = false;
		if (!StringUtils.hasLength(refName)) {
    
    
			// A reference to the id of another bean in a parent context.
			//是对父容器中另一个bean id的引用
			refName = ele.getAttribute(PARENT_REF_ATTRIBUTE);
			toParent = true;
			if (!StringUtils.hasLength(refName)) {
    
    
				error("'bean' or 'parent' is required for <ref> element", ele);
				return null;
			}
		}
        if (!StringUtils.hasText(refName)) {
    
    
            error("<ref> element contains empty target attribute", ele);
            return null;
        }
        //生成引用占位类
        RuntimeBeanReference ref = new RuntimeBeanReference(refName, toParent);
        ref.setSource(extractSource(ele));
        return ref;
    }
    else if (nodeNameEquals(ele, IDREF_ELEMENT)) {
    
    
	    //如果是idref引用
        return parseIdRefElement(ele);
    }
    else if (nodeNameEquals(ele, VALUE_ELEMENT)) {
    
    
	    //如果是value元素
        return parseValueElement(ele, defaultValueType);
    }
    else if (nodeNameEquals(ele, NULL_ELEMENT)) {
    
    
	    //如果是null元素,用null做值处理
        TypedStringValue nullHolder = new TypedStringValue(null);
        nullHolder.setSource(extractSource(ele));
        return nullHolder;
    }
    else if (nodeNameEquals(ele, ARRAY_ELEMENT)) {
    
    
	    //如果是array元素
        return parseArrayElement(ele, bd);
    }    
    else if (nodeNameEquals(ele, LIST_ELEMENT)) {
    
    
	    //如果是list元素
        return parseListElement(ele, bd);
    }
    else if (nodeNameEquals(ele, SET_ELEMENT)) {
    
    
	    //如果是set元素
        return parseSetElement(ele, bd);
    }
    else if (nodeNameEquals(ele, MAP_ELEMENT)) {
    
    
	    //如果是map元素
        return parseMapElement(ele, bd);
    }    
    else if (nodeNameEquals(ele, PROPS_ELEMENT)) {
    
    
	    //如果是props元素
        return parsePropsElement(ele);
    }
    else {
    
    
	    //以上都不是,报错
        error("Unknown property sub-element: [" + ele.getNodeName() + "]", ele);
        return null;
    }
}

The parsing of each type of element is simple and no further tracing is required.

BeanDefinitionParserDelegate.decorateBeanDefinitionIfRequired(Element ele, BeanDefinitionHolder originalDef)

Decorate the BeanDefinition as needed.

//过渡方法
public BeanDefinitionHolder decorateBeanDefinitionIfRequired(Element ele, BeanDefinitionHolder definitionHolder) {
    
    
    return decorateBeanDefinitionIfRequired(ele, definitionHolder, null);
}

//真正装饰BeanDefinition实现
public BeanDefinitionHolder decorateBeanDefinitionIfRequired(
    Element ele, BeanDefinitionHolder definitionHolder, BeanDefinition containingBd) {
    
    

    BeanDefinitionHolder finalDefinition = definitionHolder;

    // Decorate based on custom attributes first.
    // 基于属性进行
    NamedNodeMap attributes = ele.getAttributes();
    for (int i = 0; i < attributes.getLength(); i++) {
    
    
        Node node = attributes.item(i);
        finalDefinition = decorateIfRequired(node, finalDefinition, containingBd);
    }

    // Decorate based on custom nested elements.
    // 基于嵌套元素进行
    NodeList children = ele.getChildNodes();
    for (int i = 0; i < children.getLength(); i++) {
    
    
        Node node = children.item(i);
        if (node.getNodeType() == Node.ELEMENT_NODE) {
    
    
            finalDefinition = decorateIfRequired(node, finalDefinition, containingBd);
        }
    }
    return finalDefinition;
}
//装饰处理
public BeanDefinitionHolder decorateIfRequired(
			Node node, BeanDefinitionHolder originalDef, @Nullable BeanDefinition containingBd) {
    
    

		String namespaceUri = getNamespaceURI(node);
		/*显然,默认命名空间的是不需要装饰的;值装饰非默认命名空间的bean*/
		if (namespaceUri != null && !isDefaultNamespace(namespaceUri)) {
    
    
			//获取非默认命名空间的处理器
			NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
			if (handler != null) {
    
    
				//装饰处理
				BeanDefinitionHolder decorated =
						handler.decorate(node, originalDef, new ParserContext(this.readerContext, this, containingBd));
				if (decorated != null) {
    
    
					return decorated;
				}
			}
			else if (namespaceUri.startsWith("http://www.springframework.org/schema/")) {
    
    
				error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", node);
			}
			else {
    
    
				// A custom namespace, not to be handled by Spring - maybe "xml:...".
				if (logger.isDebugEnabled()) {
    
    
					logger.debug("No Spring NamespaceHandler found for XML schema namespace [" + namespaceUri + "]");
				}
			}
		}
		return originalDef;
	}

BeanDefinitionReaderUtils.registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)

Register the BeanDefinition to the container's BeanFactory

public static void registerBeanDefinition(
    BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
    throws BeanDefinitionStoreException {
    
    
    // 用beanName 注册 BeanDefinition
    String beanName = definitionHolder.getBeanName();  
    registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

    //注册别名
    String[] aliases = definitionHolder.getAliases();
    if (aliases != null) {
    
    
        for (String alias : aliases) {
    
    
            registry.registerAlias(beanName, alias);
        }
    }
}

Note: registry is actually BeanFactory, registry.registerBeanDefinition and registry.registerAlias ​​are implemented in DefaultListableBeanFactory, which is relatively simple and will no longer be tracked.

At this point, how to parse and track BeanDefinition is completed. For how to use it, please refer to: Learn SF Framework Series 5.7-Module Beans-BeanDefinition Usage.

Guess you like

Origin blog.csdn.net/davidwkx/article/details/131580383