Vamos aprender a análise da série SF framework 5.7-spring-Beans-BeanDefinition juntos

Os desenvolvedores definem os beans de aplicação de acordo com as regras de metadados. Compreender como o SF é analisado no BeanDefiniton de acordo com a definição pode ajudar a compreender profundamente a implementação da estrutura. O processo de análise é o seguinte:

Carregamento de recursos

O processo real de carregamento da configuração de metadados do bean do arquivo de recurso é o seguinte: o
Insira a descrição da imagem aqui
carregamento real da definição do bean do arquivo XML especificado começa com XmlBeanDefinitionReader.doLoadBeanDefinitions.

analisar

A análise consiste em duas etapas principais:
1. Analisar o conteúdo do arquivo de recursos em um documento DOM por meio de um analisador SAX.
2. Gerar
o código-fonte BeanDefinition (XmlBeanDefinitionReader.doLoadBeanDefinitions) a partir do documento DOM:

	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);
		}
	}

Arquivos de recursos para documento

A implementação do Spring é relativamente complexa. O diagrama de relacionamento básico é o seguinte:
Insira a descrição da imagem aqui
Ele usa principalmente SAX para analisar metadados no formato XML em documentos DOM. Tem pouco a ver com o propósito do Spring em si. Não há necessidade de rastrear o código em detalhe. Os alunos interessados ​​​​podem aprender e entender por si mesmos.

Documento para BeanDefinition

Processo principal

Insira a descrição da imagem aqui

XmlBeanDefinitionReader.registerBeanDefinitions (documento, recurso de recurso)

	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 (documento, XmlReaderContext readerContext)

É óbvio à primeira vista.

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

BeanDefinitionDocumentReader.doRegisterBeanDefinitions (raiz do elemento)

Comece a análise a partir do elemento raiz do bean ( ).

	//不理解怎么成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;
	}

Nota 1 O que é perfil, consulte: Aprendam juntos o SF Framework Series 6.2 - módulo core-Environment

BeanDefinitionDocumentReader.parseBeanDefinitions (elemento raiz, delegado BeanDefinitionParserDelegate)

Gere BeanDefinition e registre-o no 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);
		}
	}

Nota 1: A compreensão do namespace é a seguinte: Um namespace corresponde a um processador de análise:
Se a configuração de anotação estiver habilitada, a linha a seguir precisa ser adicionada ao arquivo de configuração do Spring applicationContext.xml:
<context:annotation-config />
significa a anotação do rótulo -config pertence ao contexto do namespace. contexto corresponde a um processador de análise. Ao analisar, você precisa primeiro obter o processador de análise correspondente ao contexto. O processador de análise inicializará alguns analisadores e um analisador corresponde a uma tag.
Rastreie com base em como o namespace padrão é resolvido.

BeanDefinitionDocumentReader.parseDefaultElement(elemento elemento, delegado BeanDefinitionParserDelegate)

Resolução de elemento para o namespace padrão.

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);
    }
}

Rastreie para baixo com base nos beans gerados.

BeanDefinitionDocumentReader.processBeanDefinition(elemento elemento, delegado BeanDefinitionParserDelegate)

Analise o elemento bean em um BeanDefinition e registre-o no 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(elemento elemento)

//Analisa os elementos em 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;
}

Nota 1: Para entender os relacionamentos de id, nome e alias dos beans, consulte: Aprenda SF Framework Series 5.1-Module Beans-bean Overview

BeanDefinitionParserDelegate.parseBeanDefinitionElement(Elemento ele, String beanName, @Nullable BeanDefinition contendoBean)

Ele não presta atenção ao nome e alias do bean, mas apenas analisa o próprio BeanDefinition.

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)

Crie BeanDefinition e defina as propriedades: parentName e 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(Elemento ele, String beanName, @Nullable BeanDefinition contendoBean, AbstractBeanDefinition bd)

Analisar configurações de definição de bean em propriedades BeanDefinition

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(Elemento beanEle, BeanDefinition bd)

Analise o valor da propriedade do 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;
    }
}

A análise de cada tipo de elemento é simples e nenhum rastreamento adicional é necessário.

BeanDefinitionParserDelegate.decorateBeanDefinitionIfRequired (elemento elemento, BeanDefinitionHolder originalDef)

Decore o BeanDefinition conforme necessário.

//过渡方法
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 definiçãoHolder, registro BeanDefinitionRegistry)

Registre o BeanDefinition no BeanFactory do contêiner

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);
        }
    }
}

Nota: o registro é na verdade BeanFactory, Registry.registerBeanDefinition e Registry.registerAlias ​​​​são implementados em DefaultListableBeanFactory, que é relativamente simples e não será mais rastreado.

Neste ponto, como analisar e rastrear BeanDefinition está concluído. Para saber como usá-lo, consulte: Aprenda o uso do SF Framework Series 5.7-Module Beans-BeanDefinition.

Acho que você gosta

Origin blog.csdn.net/davidwkx/article/details/131580383
Recomendado
Clasificación