Four kinds of basic analytical principles of spring labels

  • Kinds of tags

Four basic tags present in the spring configuration file are: beans, bean, import, alias

Kinds of tags functions:

beans: define a single application configuration (test configuration, development configuration, etc.), when the deployment server can choose which application deployment configuration

bean: The most basic definition of an object

import: Import Profiles

alias: alias is defined bean

  • Entrance resolved

spring to complete the parsing of the xml configuration file with a sax parser, the xml tags in the creation of a document into a tree in memory.

protected  void doRegisterBeanDefinitions (the Element the root) { 
        
        BeanDefinitionParserDelegate parent = the this .delegate; 
         the this .delegate = createDelegate This (getReaderContext (), the root, parent); 

        IF ( the this .delegate.isDefaultNamespace (the root)) {   // documentation <beans> tag tag as the root of the following determination 
            String profileSpec = root.getAttribute (PROFILE_ATTRIBUTE); // retrieving profile attributes of the tag judgment profile attributes beans 
            IF (StringUtils.hasText (profileSpec)) { 
                String [] specifiedProfiles = StringUtils.tokenizeToStringArray (
                        profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS); // the value of the property profile according to the delimiter string array into IF (getReaderContext (!) getEnvironment () acceptsProfiles (specifiedProfiles)) {.. // When the value of a given property profile all did not continue to activate the next load xml 
                    IF (logger.isInfoEnabled ()) { 
                        logger.info ( "Skipped bean XML Definition File Due to specified Profiles [" + profileSpec + 
                                "] not matching:" + getReaderContext (). the getResource ()); 
                    } 
                    return ; 
                } 
            } 
        } 

        preProcessXml (the root); //If a user override this method indicates the operation before loading bean, inport, beans, alias and other labels to be executed 
        parseBeanDefinitions (the root, the this .delegate); // loading bean, inport, beans, alias and other labels 
        postProcessXml (the root); / / user override this method if the loading operation is represented bean, inport, beans, alias tag that should be executed like 

        the this .delegate = parent; 
    }

The main operation described above is <beans profiles = ""> <beans /> tag operation, there may be a plurality of beans in the xml file tags, each tag beans can define a project configuration profiles can be named this configuration, spring framework will load the corresponding configuration of the activation of the profiles.

 Activation profiles of several ways:
 as an initialization parameter SpringMVC in the DispatcherServlet
 as initialization parameters Web application context
 as the entrance of JNDI
 as an environment variable (Windows environment variable to add windows server)
 as the system parameters of the virtual machine (linux is server, in ~ / .bash_profile in the last line export SPRING_PROFILES_ACTIVE = dev)
 used to activate @AtivceProfile

  • 1-beanname analytical analysis of bean tag

Below resolve the root tag

public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
        String id = ele.getAttribute(ID_ATTRIBUTE);  
        String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);

        List<String> aliases = new ArrayList<String>();
        if (StringUtils.hasLength(nameAttr)) {
            String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
            aliases.addAll(Arrays.asList(nameArr));
        }  //将多个name存储到aliases

        String beanName =ID;
         IF (!! StringUtils.hasText (the beanName) && aliases.isEmpty ()) { 
            the beanName = aliases.remove (0 );
             IF (logger.isDebugEnabled ()) { 
                logger.debug ( "No the XML 'ID' specified - the using ' "+ the beanName + 
                        "' AS bean name and "+ + aliases" aliases AS " ); 
            } 
        } // if no bean tag id attribute value will be assigned to the first name of the bean name or id value beanname 

        IF (containingBean == null ) { 
            checkNameUniqueness (the beanName, aliases, ELE); // Analyzing bean name has not been loaded through 
        }

        AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean); //解析<bean>里面的标签
        if (beanDefinition != null) {
            if (!StringUtils.hasText(beanName)) {
                try {
                    if (containingBean != null) {
                        beanName = BeanDefinitionReaderUtils.generateBeanName(
                                beanDefinition, this.readerContext.getRegistry(), true);
                    }
                    else {
                        beanName = the this .readerContext.generateBeanName (BeanDefinition); // based on the class name to generate a unique name as # 0 className 
                        
                        String beanClassName = beanDefinition.getBeanClassName (); // true class name 
                        IF ! (beanClassName = null && 
                                beanName.startsWith (beanClassName) && beanName.length ()> beanClassName.length () && 
                                ! the this .readerContext.getRegistry () isBeanNameInUse (beanClassName)) {. 
                            aliases.add (beanClassName); 
                        } //If no aliases are registered before the actual class is registered into the name or register 
                    }
                     IF (logger.isDebugEnabled ()) { 
                        logger.debug ( "Neither the XML 'ID' NOR 'name' specified -" + 
                                "the using the bean name Generated [ "the beanName + +"] " ); 
                    } 
                } 
                the catch (Exception EX) { 
                    error (ex.getMessage (), ELE); 
                    return  null ; 
                } 
            } 
            String [] aliasesArray = StringUtils.toStringArray (aliases);
             return  new new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
        }

        return null;
    }

The above code is mainly acquired beanname

1. id attribute id is taken beanname

2 there then take the first attribute is a name attribute beanname

3 external bean (i.e., currently being created just another bean bean property) if the parent take parentbean beanname plus plus $ child hashcode automatically generated, but if no parent plus $ create factorybeanname take factorybeanname plus the system automatically generated hashcode

4. No external bean, and then determines whether there is named as if parentbean parentbeanname generated according to the number $ child # 0, parentbeanname $ child # 1 ........; but if not parentbean generated according factorybeanname the number of named factorybeanname $ create # 0, factorybeanname $ create # 1 ......

  • Analytical 2-attribute analysis of bean tag

  

public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName,
            BeanDefinition containingBean, AbstractBeanDefinition bd) {

        if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) {
            error("Old 1.x 'singleton' attribute in use - upgrade to 'scope' declaration", ele);
        }
        else if (ele.hasAttribute(SCOPE_ATTRIBUTE)) {
            bd.setScope(ele.getAttribute(SCOPE_ATTRIBUTE));
        }
        else if (containingBean != null) {
            // Take default from containing bean in case of an inner bean definition.
            bd.setScope(containingBean.getScope());
        }

        if (ele.hasAttribute(ABSTRACT_ATTRIBUTE)) {
            bd.setAbstract(TRUE_VALUE.equals(ele.getAttribute(ABSTRACT_ATTRIBUTE)));
        }

        String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE);
        if (DEFAULT_VALUE.equals(lazyInit)) {
            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);
            bd.setDependsOn(StringUtils.tokenizeToStringArray(dependsOn, MULTI_VALUE_ATTRIBUTE_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);
            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)) {
            bd.setFactoryBeanName(ele.getAttribute(FACTORY_BEAN_ATTRIBUTE));
        }

        return bd;
    }

 

The code contains a pair of <bean> tag property worth parsed attribute values ​​including: scope, singleton, abstract, lazy-init, autowire, dependcy-check, depends-on, autowire-candidate, primary, init-method, destroy- method, factory-method, factory-bean

The next element is a tag within the <bean> tag resolution. Specific resolution procedures similar: the value of the node element corresponding to the type of taken into beandefinition

       parseMetaElements (ELE, BD); // Analytical <meta key = '' value = ''> metadata tags, key-value pairs in the attributeAccessor 
            parseLookupOverrideSubElements (ELE, bd.getMethodOverrides ()); // dynamically generated proxy class 
            parseReplacedMethodSubElements (ELE, bd.getMethodOverrides ()); 

            parseConstructorArgElements (ELE, BD);   // analytical <constructor-arg index = '' type = '' name = '' /> properties 
            parsePropertyElements (ELE, BD); // analytical < property name = '' /> properties 
            parseQualifierElements (ELE, BD); // analytical <qualifier type = '' value = ''> <attribute key = '' vaule = '' /> <qualifier>
  • Parses meta tags

 

public void parseMetaElements(Element ele, BeanMetadataAttributeAccessor attributeAccessor) {
        NodeList nl = ele.getChildNodes();
        for (int i = 0; i < nl.getLength(); i++) {
            Node node = nl.item(i);
            if (isCandidateElement(node) && nodeNameEquals(node, META_ELEMENT)) {
                Element metaElement = (Element) node;
                String key = metaElement.getAttribute(KEY_ATTRIBUTE);
                String value = metaElement.getAttribute(VALUE_ATTRIBUTE);
                BeanMetadataAttribute attribute = new BeanMetadataAttribute(key, value);
                attribute.setSource(extractSource(metaElement));
                attributeAccessor.addMetadataAttribute(attribute);
            }
        }
    }

 

The key attributes and value of meta tags into beandefinition

  • Resolve Lookup-method tag
public void parseLookupOverrideSubElements(Element beanEle, MethodOverrides overrides) {
        NodeList nl = beanEle.getChildNodes();
        for (int i = 0; i < nl.getLength(); i++) {
            Node node = nl.item(i);
            if (isCandidateElement(node) && nodeNameEquals(node, LOOKUP_METHOD_ELEMENT)) {
                Element ele = (Element) node;
                String methodName = ele.getAttribute(NAME_ATTRIBUTE);
                String beanRef = ele.getAttribute(BEAN_ELEMENT);
                LookupOverride override = new LookupOverride(methodName, beanRef);
                override.setSource(extractSource(ele));
                overrides.addOverride(override);
            }
        }
    }
 

The name tag lookup-mathod onto bean properties and beandefinition

  • replace-method of parsing
public void parseReplacedMethodSubElements(Element beanEle, MethodOverrides overrides) {
        NodeList nl = beanEle.getChildNodes();
        for (int i = 0; i < nl.getLength(); i++) {
            Node node = nl.item(i);
            if (isCandidateElement(node) && nodeNameEquals(node, REPLACED_METHOD_ELEMENT)) {
                Element replacedMethodEle = (Element) node;
                String name = replacedMethodEle.getAttribute(NAME_ATTRIBUTE);
                String callback = replacedMethodEle.getAttribute(REPLACER_ATTRIBUTE);
                ReplaceOverride replaceOverride = new ReplaceOverride(name, callback);
                // Look for arg-type match elements.
                List<Element> argTypeEles = DomUtils.getChildElementsByTagName(replacedMethodEle, ARG_TYPE_ELEMENT);
                for (Element argTypeEle : argTypeEles) {
                    String match = argTypeEle.getAttribute(ARG_TYPE_MATCH_ATTRIBUTE);
                    match = (StringUtils.hasText(match) ? match : DomUtils.getTextValue(argTypeEle));
                    if (StringUtils.hasText(match)) {
                        replaceOverride.addTypeIdentifier(match);
                    }
                }
                replaceOverride.setSource(extractSource(replacedMethodEle));
                overrides.addOverride(replaceOverride);
            }
        }
    }

 The replace-mathod tag name and attributes into the bean beandefinition

  • constructor-arg parsing

public void parseConstructorArgElements(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, CONSTRUCTOR_ARG_ELEMENT)) {
                parseConstructorArgElement((Element) node, bd);
            }
        }
    }

 

public void parseConstructorArgElement(Element ele, BeanDefinition bd) {
        String indexAttr = ele.getAttribute(INDEX_ATTRIBUTE);
        String typeAttr = ele.getAttribute(TYPE_ATTRIBUTE);
        String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
        if (StringUtils.hasLength(indexAttr)) {
            try {
                int index = Integer.parseInt(indexAttr);
                if (index < 0) {
                    error("'index' cannot be lower than 0", ele);
                }
                else {
                    try {
                        this.parseState.push(new ConstructorArgumentEntry(index));
                        Object value = parsePropertyValue(ele, bd, null);
                        ConstructorArgumentValues.ValueHolder valueHolder = new ConstructorArgumentValues.ValueHolder(value);
                        if (StringUtils.hasLength(typeAttr)) {
                            valueHolder.setType(typeAttr);
                        }
                        if (StringUtils.hasLength(nameAttr)) {
                            valueHolder.setName(nameAttr);
                        }
                        valueHolder.setSource(extractSource(ele));
                        if (bd.getConstructorArgumentValues().hasIndexedArgumentValue(index)) {
                            error("Ambiguous constructor-arg entries for index " + index, ele);
                        }
                        else {
                            bd.getConstructorArgumentValues().addIndexedArgumentValue(index, valueHolder);
                        }
                    }
                    finally {
                        this.parseState.pop();
                    }
                }
            }
            catch (NumberFormatException ex) {
                error("Attribute 'index' of tag 'constructor-arg' must be an integer", ele);
            }
        }
        else {
            try {
                this.parseState.push(new ConstructorArgumentEntry());
                Object value = parsePropertyValue(ele, bd, null);
                ConstructorArgumentValues.ValueHolder valueHolder = new ConstructorArgumentValues.ValueHolder(value);
                if (StringUtils.hasLength(typeAttr)) {
                    valueHolder.setType(typeAttr);
                }
                if (StringUtils.hasLength(nameAttr)) {
                    valueHolder.setName(nameAttr);
                }
                valueHolder.setSource(extractSource(ele));
                bd.getConstructorArgumentValues().addGenericArgumentValue(valueHolder);
            }
            finally {
                this.parseState.pop();
            }
        }
    }

  

The code sub-tags and attribute values ​​constructor tag parses

 

  •  Resolve property label

 

public void parseQualifierElements(Element beanEle, AbstractBeanDefinition bd) {
        NodeList nl = beanEle.getChildNodes();
        for (int i = 0; i < nl.getLength(); i++) {
            Node node = nl.item(i);
            if (isCandidateElement(node) && nodeNameEquals(node, QUALIFIER_ELEMENT)) {
                parseQualifierElement((Element) node, bd);
            }
        }
    }

 

 

public void parseQualifierElement(Element ele, AbstractBeanDefinition bd) {
        String typeName = ele.getAttribute(TYPE_ATTRIBUTE);
        if (!StringUtils.hasLength(typeName)) {
            error("Tag 'qualifier' must have a 'type' attribute", ele);
            return;
        }
        this.parseState.push(new QualifierEntry(typeName));
        try {
            AutowireCandidateQualifier qualifier = new AutowireCandidateQualifier(typeName);
            qualifier.setSource(extractSource(ele));
            String value = ele.getAttribute(VALUE_ATTRIBUTE);
            if (StringUtils.hasLength(value)) {
                qualifier.setAttribute(AutowireCandidateQualifier.VALUE_KEY, value);
            }
            NodeList nl = ele.getChildNodes();
            for (int i = 0; i < nl.getLength(); i++) {
                Node node = nl.item(i);
                if (isCandidateElement(node) && nodeNameEquals(node, QUALIFIER_ATTRIBUTE_ELEMENT)) {
                    Element attributeEle = (Element) node;
                    String attributeName = attributeEle.getAttribute(KEY_ATTRIBUTE);
                    String attributeValue = attributeEle.getAttribute(VALUE_ATTRIBUTE);
                    if (StringUtils.hasLength(attributeName) && StringUtils.hasLength(attributeValue)) {
                        BeanMetadataAttribute attribute = new BeanMetadataAttribute(attributeName, attributeValue);
                        attribute.setSource(extractSource(attributeEle));
                        qualifier.addMetadataAttribute(attribute);
                    }
                    else {
                        error("Qualifier 'attribute' tag must have a 'name' and 'value'", attributeEle);
                        return;
                    }
                }
            }
            bd.addQualifier(qualifier);
        }
        finally {
            this.parseState.pop();
        }
    }

The code iterates complete extraction property tag label element.

  • Parse parse qualifier label

public void parseQualifierElements(Element beanEle, AbstractBeanDefinition bd) {
        NodeList nl = beanEle.getChildNodes();
        for (int i = 0; i < nl.getLength(); i++) {
            Node node = nl.item(i);
            if (isCandidateElement(node) && nodeNameEquals(node, QUALIFIER_ELEMENT)) {
                parseQualifierElement((Element) node, bd);
            }
        }
    }
public void parseQualifierElement(Element ele, AbstractBeanDefinition bd) {
        String typeName = ele.getAttribute(TYPE_ATTRIBUTE);
        if (!StringUtils.hasLength(typeName)) {
            error("Tag 'qualifier' must have a 'type' attribute", ele);
            return;
        }
        this.parseState.push(new QualifierEntry(typeName));
        try {
            AutowireCandidateQualifier qualifier = new AutowireCandidateQualifier(typeName);
            qualifier.setSource(extractSource(ele));
            String value = ele.getAttribute(VALUE_ATTRIBUTE);
            if (StringUtils.hasLength(value)) {
                qualifier.setAttribute(AutowireCandidateQualifier.VALUE_KEY, value);
            }
            NodeList nl = ele.getChildNodes();
            for (int i = 0; i < nl.getLength(); i++) {
                Node node = nl.item(i);
                if (isCandidateElement(node) && nodeNameEquals(node, QUALIFIER_ATTRIBUTE_ELEMENT)) {
                    Element attributeEle = (Element) node;
                    String attributeName = attributeEle.getAttribute(KEY_ATTRIBUTE);
                    String attributeValue = attributeEle.getAttribute(VALUE_ATTRIBUTE);
                    if (StringUtils.hasLength(attributeName) && StringUtils.hasLength(attributeValue)) {
                        BeanMetadataAttribute attribute = new BeanMetadataAttribute(attributeName, attributeValue);
                        attribute.setSource(extractSource(attributeEle));
                        qualifier.addMetadataAttribute(attribute);
                    }
                    else {
                        error("Qualifier 'attribute' tag must have a 'name' and 'value'", attributeEle);
                        return;
                    }
                }
            }
            bd.addQualifier(qualifier);
        }
        finally {
            this.parseState.pop();
        }
    }

The code qualifier complete extraction elements

 

Guess you like

Origin www.cnblogs.com/ll9507/p/11298221.html