Spring学习笔记

解析默认Bean标签

Spring默认标签有四个,分别是import、alias、bean、beans,其中关于bean的逻辑最为复杂,所以我们首先从bean标签开始分析,只要掌握了bean标签的逻辑,那么其他标签也不在话下。

private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
        //解析import标签
        if (delegate.nodeNameEquals(ele, "import")) {
            this.importBeanDefinitionResource(ele);
        //解析alias标签
        } else if (delegate.nodeNameEquals(ele, "alias")) {
            this.processAliasRegistration(ele);
        //解析bean标签
        } else if (delegate.nodeNameEquals(ele, "bean")) {
            this.processBeanDefinition(ele, delegate);
        //解析beans标签
        } else if (delegate.nodeNameEquals(ele, "beans")) {
            this.doRegisterBeanDefinitions(ele);
        }

    }

Bean标签解析

processBeanDefinition

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
        //通过该方法,委托BeanDefinitionParserDelegate解析元素
        BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
        if (bdHolder != null) {
            //判断当前的bean是否需要修饰
            bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);

            try {
                //注册bean
                BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.getReaderContext().getRegistry());
            } catch (BeanDefinitionStoreException var5) {
                this.getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, var5);
            }
            //通知上下文bean注册成功
            this.getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
        }

    }

Spring如何解析和提取配置文件的信息的呢?我们进入方法delegate.parseBeanDefinitionElement(ele):

 public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {
        //获取id属性
        String id = ele.getAttribute("id");
        //获取name属性
        String nameAttr = ele.getAttribute("name");
        List<String> aliases = new ArrayList();
        //将name按照“,;”切割
        if (StringUtils.hasLength(nameAttr)) {
            String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, ",; ");
            //存入集合中
            aliases.addAll(Arrays.asList(nameArr));
        }
        //将id设为beanName
        String beanName = id;
        //如果id为空,alises不为空
        if (!StringUtils.hasText(id) && !aliases.isEmpty()) {
            //将alises的第一个元素作为beanName
            beanName = (String)aliases.remove(0);
            if (this.logger.isTraceEnabled()) {
                this.logger.trace("No XML 'id' specified - using '" + beanName + "' as bean name and " + aliases + " as aliases");
            }
        }
        //校验beanName是否唯一
        if (containingBean == null) {
            this.checkNameUniqueness(beanName, aliases, ele);
        }
        //解析bean信息元素
        AbstractBeanDefinition beanDefinition = this.parseBeanDefinitionElement(ele, beanName, containingBean);
        if (beanDefinition != null) {
            if (!StringUtils.hasText(beanName)) {
                try {
                    if (containingBean != null) {
                        //如果不存在beanName,那么使用Spring的命名规则为当前Bean生成beanName
                        //bean配置在xml文件中如果设置了class: 那么以class全路径作为beanName
                        //如果没有设置class:检查是否设置了parent属性,如果设置了parent,则beanName=parentName+"$child";
                        //否则检查是否设置了factory-bean属性,如果设置了,那么已factory-bean + "$created" 作为beanName检测生成的beanName是否已被注册,如果被注册,那么以一个数字作为后缀区分
                        beanName = BeanDefinitionReaderUtils.generateBeanName(beanDefinition, this.readerContext.getRegistry(), true);
                    } else {
                        beanName = this.readerContext.generateBeanName(beanDefinition);
                        //获取bean的className
                        String beanClassName = beanDefinition.getBeanClassName();
                        if (beanClassName != null && beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() && !this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
                            aliases.add(beanClassName);
                        }
                    }

                    if (this.logger.isTraceEnabled()) {
                        this.logger.trace("Neither XML 'id' nor 'name' specified - using generated bean name [" + beanName + "]");
                    }
                } catch (Exception var9) {
                    this.error(var9.getMessage(), ele);
                    return null;
                }
            }

            String[] aliasesArray = StringUtils.toStringArray(aliases);
            //封装到BeanDefinitionHolder中
            return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
        } else {
            return null;
        }
    }

校验beanName是否唯一:

this.checkNameUniqueness(beanName, aliases, ele)

    protected void checkNameUniqueness(String beanName, List<String> aliases, Element beanElement) {
        String foundName = null;
        //如果beanName不为空并且使用的name中包含了beanName
        if (StringUtils.hasText(beanName) && this.usedNames.contains(beanName)) {
            //给foundName赋值
            foundName = beanName;
        }
        //如果在使用的name中匹配到了别名
        if (foundName == null) {
            //给foundName赋值
            foundName = (String)CollectionUtils.findFirstMatch(this.usedNames, aliases);
        }
        //当foundName不为空,说明此名字已经被使用过
        if (foundName != null) {
            this.error("Bean name '" + foundName + "' is already used in this <beans> element", beanElement);
        }
        //否则就将beanName和alises都存入集合中
        this.usedNames.add(beanName);
        this.usedNames.addAll(aliases);
    }

解析bean的信息元素

this.parseBeanDefinitionElement(ele, beanName, containingBean)

 public AbstractBeanDefinition parseBeanDefinitionElement(Element ele, String beanName, @Nullable BeanDefinition containingBean) {
        this.parseState.push(new BeanEntry(beanName));
        String className = null;
        //获取class属性
        if (ele.hasAttribute("class")) {
            className = ele.getAttribute("class").trim();
        }

        String parent = null;
        //获取parent属性
        if (ele.hasAttribute("parent")) {
            parent = ele.getAttribute("parent");
        }

        try {
            //创建保存属性的载体AbstractBeanDefinition
            //其包含了配置文件中的所有属性并且一一对应
            AbstractBeanDefinition bd = this.createBeanDefinition(className, parent);
            //解析默认bean的属性
            this.parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
            //设置说明
            bd.setDescription(DomUtils.getChildElementValueByTagName(ele, "description"));
            //解析元数据
            this.parseMetaElements(ele, bd);
            //解析lookUp方法
            this.parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
            //解析replace方法
            this.parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
            //解析constructor-arg
            this.parseConstructorArgElements(ele, bd);
            //解析properties属性
            this.parsePropertyElements(ele, bd);
            //解析qualifier属性
            this.parseQualifierElements(ele, bd);
            bd.setResource(this.readerContext.getResource());
            bd.setSource(this.extractSource(ele));
            AbstractBeanDefinition var7 = bd;
            return var7;
        } catch (ClassNotFoundException var13) {
            this.error("Bean class [" + className + "] not found", ele, var13);
        } catch (NoClassDefFoundError var14) {
            this.error("Class that bean class [" + className + "] depends on not found", ele, var14);
        } catch (Throwable var15) {
            this.error("Unexpected failure during bean definition parsing", ele, var15);
        } finally {
            this.parseState.pop();
        }

        return null;
    }

解析默认bean标签

this.parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);

 public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName, @Nullable BeanDefinition containingBean, AbstractBeanDefinition bd) {
        //如果存在singleton属性,直接抛出异常
        if (ele.hasAttribute("singleton")) {
            this.error("Old 1.x 'singleton' attribute in use - upgrade to 'scope' declaration", ele);
        //获取scope属性
        } else if (ele.hasAttribute("scope")) {
            bd.setScope(ele.getAttribute("scope"));
        } else if (containingBean != null) {
            //当存在嵌入beanDefinition且未单独指定scope时,默认使用父类的scope
            bd.setScope(containingBean.getScope());
        }
        //获取abstract属性
        if (ele.hasAttribute("abstract")) {
            //当abstract设置其他非true的值或者为设置时,均为false
            bd.setAbstract("true".equals(ele.getAttribute("abstract")));
        }
        //获取lazy-init属性
        String lazyInit = ele.getAttribute("lazy-init");
        if (this.isDefaultValue(lazyInit)) {
            lazyInit = this.defaults.getLazyInit();
        }
        //同上
        bd.setLazyInit("true".equals(lazyInit));
        //获取autowire属性
        String autowire = ele.getAttribute("autowire");
        //设置自动注入的方式
        //1 ==> byName
        //2 ==> byType
        //3 ==> constructor
        //4 ==> autodetect
        bd.setAutowireMode(this.getAutowireMode(autowire));
        //解析depends-on属性
        String autowireCandidate;
        if (ele.hasAttribute("depends-on")) {
            autowireCandidate = ele.getAttribute("depends-on");
            bd.setDependsOn(StringUtils.tokenizeToStringArray(autowireCandidate, ",; "));
        }
         //解析autowire-candidate属性
        autowireCandidate = ele.getAttribute("autowire-candidate");
        String destroyMethodName;
        if (this.isDefaultValue(autowireCandidate)) {
            destroyMethodName = this.defaults.getAutowireCandidates();
            if (destroyMethodName != null) {
                String[] patterns = StringUtils.commaDelimitedListToStringArray(destroyMethodName);
                bd.setAutowireCandidate(PatternMatchUtils.simpleMatch(patterns, beanName));
            }
        } else {
            bd.setAutowireCandidate("true".equals(autowireCandidate));
        }
        //解析primary属性
        if (ele.hasAttribute("primary")) {
            bd.setPrimary("true".equals(ele.getAttribute("primary")));
        }
        //解析init-method属性
        if (ele.hasAttribute("init-method")) {
            destroyMethodName = ele.getAttribute("init-method");
            bd.setInitMethodName(destroyMethodName);
        } else if (this.defaults.getInitMethod() != null) {
            bd.setInitMethodName(this.defaults.getInitMethod());
            bd.setEnforceInitMethod(false);
        }
        //解析destroy-method属性
        if (ele.hasAttribute("destroy-method")) {
            destroyMethodName = ele.getAttribute("destroy-method");
            bd.setDestroyMethodName(destroyMethodName);
        } else if (this.defaults.getDestroyMethod() != null) {
            bd.setDestroyMethodName(this.defaults.getDestroyMethod());
            bd.setEnforceDestroyMethod(false);
        }
        //解析factory-method属性
        if (ele.hasAttribute("factory-method")) {
            bd.setFactoryMethodName(ele.getAttribute("factory-method"));
        }
        //解析factory-bean属性
        if (ele.hasAttribute("factory-bean")) {
            bd.setFactoryBeanName(ele.getAttribute("factory-bean"));
        }
        //将属性封装到AbstractBeanDefinition中
        return bd;
    }

解析元数据

this.parseMetaElements(ele, bd);

public void parseMetaElements(Element ele, BeanMetadataAttributeAccessor attributeAccessor) {
        //获取所有的子节点
        NodeList nl = ele.getChildNodes();
        //循环遍历子节点
        for(int i = 0; i < nl.getLength(); ++i) {
            Node node = nl.item(i);
            //提取matedata
            if (this.isCandidateElement(node) && this.nodeNameEquals(node, "meta")) {
                Element metaElement = (Element)node;
                String key = metaElement.getAttribute("key");
                String value = metaElement.getAttribute("value");
                //以key value形式保存元数据至BeanMetadataAttribute中
                BeanMetadataAttribute attribute = new BeanMetadataAttribute(key, value);
                attribute.setSource(this.extractSource(metaElement));
                attributeAccessor.addMetadataAttribute(attribute);
            }
        }

    }

解析lookup-method

this.parseLookupOverrideSubElements(ele, bd.getMethodOverrides())

<bean class="com.gongj.lookupMethod.Banana" id="banana"></bean>
    <bean class="com.gongj.lookupMethod.TestLookupMethod" id="lookupMethod">
        <lookup-method name="getBean" bean="banana"></lookup-method>
    </bean>
public void parseLookupOverrideSubElements(Element beanEle, MethodOverrides overrides) {
        //获取所有的子节点
        NodeList nl = beanEle.getChildNodes();
        //遍历
        for(int i = 0; i < nl.getLength(); ++i) {
            Node node = nl.item(i);
            //如果是Spring默认的节点,并且是<lookup-method时生效
            if (this.isCandidateElement(node) && this.nodeNameEquals(node, "lookup-method")) {
                Element ele = (Element)node;
                //需要修饰的方法名
                String methodName = ele.getAttribute("name");
                //替换后的bean
                String beanRef = ele.getAttribute("bean");
                // 根据 methodName、beanRef 构建 LookupOverride 对象
                LookupOverride override = new LookupOverride(methodName, beanRef);
                override.setSource(this.extractSource(ele));
                //保存
                overrides.addOverride(override);
            }
        }

    }

解析replaced-method元素

this.parseReplacedMethodSubElements(ele, bd.getMethodOverrides())

<bean class="com.gongj.lookupMethod.Replaced" id="replaced">
        <replaced-method name="replacedName" replacer="replacedMethod">
<!--<arg-type></arg-type>可以配置任意多个 取决于想替换哪个重载方法-->
            <arg-type>String</arg-type>
            <arg-type>Integer</arg-type>
        </replaced-method>
    </bean>

    <!-- replacedMethod -->
    <bean class="com.gongj.lookupMethod.TestReplacedMethod" id="replacedMethod"></bean>
public void parseReplacedMethodSubElements(Element beanEle, MethodOverrides overrides) {
        //获取所有的子节点
        NodeList nl = beanEle.getChildNodes();
        //遍历
        for(int i = 0; i < nl.getLength(); ++i) {
            Node node = nl.item(i);
            //如果是Spring默认标签并且是<replaced-method开头时生效
            if (this.isCandidateElement(node) && this.nodeNameEquals(node, "replaced-method")) {
                Element replacedMethodEle = (Element)node;
                //被替换的方法
                String name = replacedMethodEle.getAttribute("name");
                //替换后的方法
                String callback = replacedMethodEle.getAttribute("replacer");
                 // 根据 name、replacer 构建 ReplaceOverride 对象
                ReplaceOverride replaceOverride = new ReplaceOverride(name, callback);
                //寻找arg-type元素
                List<Element> argTypeEles = DomUtils.getChildElementsByTagName(replacedMethodEle, "arg-type");
                Iterator var11 = argTypeEles.iterator();

                while(var11.hasNext()) {
                    //记录参数
                    Element argTypeEle = (Element)var11.next();
                    String match = argTypeEle.getAttribute("match");
                    match = StringUtils.hasText(match) ? match : DomUtils.getTextValue(argTypeEle);
                    if (StringUtils.hasText(match)) {
                        replaceOverride.addTypeIdentifier(match);
                    }
                }

                replaceOverride.setSource(this.extractSource(replacedMethodEle));
                // 将该对象添加到 MethodOverrides对象里的 overrides集合中
                overrides.addOverride(replaceOverride);
            }
        }

    }

解析子元素constructor-arg标签

this.parseConstructorArgElements(ele, bd)

 public void parseConstructorArgElements(Element beanEle, BeanDefinition bd) {
        //获取子节点
        NodeList nl = beanEle.getChildNodes();
        //遍历
        for(int i = 0; i < nl.getLength(); ++i) {
            Node node = nl.item(i);
            //当是Spring默认标签并且以<constructor-arg开头时生效
            if (this.isCandidateElement(node) && this.nodeNameEquals(node, "constructor-arg")) {
                //解析
                this.parseConstructorArgElement((Element)node, bd);
            }
        }

    }

this.parseConstructorArgElement((Element)node, bd)

 public void parseConstructorArgElement(Element ele, BeanDefinition bd) {
        //获取index属性
        String indexAttr = ele.getAttribute("index");
        //获取type属性
        String typeAttr = ele.getAttribute("type");
        //获取name属性
        String nameAttr = ele.getAttribute("name");
        //当存在index标签时
        if (StringUtils.hasLength(indexAttr)) {
            try {
                int index = Integer.parseInt(indexAttr);
                if (index < 0) {
                    this.error("'index' cannot be lower than 0", ele);
                } else {
                    try {
                        //保存一个ConstructorArgumentEntry实例对象
                        this.parseState.push(new ConstructorArgumentEntry(index));
                        //解析properties的值
                        Object value = this.parsePropertyValue(ele, bd, (String)null);
                        ValueHolder valueHolder = new ValueHolder(value);
                        if (StringUtils.hasLength(typeAttr)) {
                            valueHolder.setType(typeAttr);
                        }

                        if (StringUtils.hasLength(nameAttr)) {
                            valueHolder.setName(nameAttr);
                        }
                        //保存到ValueHolder
                        valueHolder.setSource(this.extractSource(ele));
                        //不允许重复指定参数
                        if (bd.getConstructorArgumentValues().hasIndexedArgumentValue(index)) {
                            this.error("Ambiguous constructor-arg entries for index " + index, ele);
                        } else {
                            保存至indexedArgumentValue
                            bd.getConstructorArgumentValues().addIndexedArgumentValue(index, valueHolder);
                        }
                    } finally {
                        this.parseState.pop();
                    }
                }
            } catch (NumberFormatException var19) {
                this.error("Attribute 'index' of tag 'constructor-arg' must be an integer", ele);
            }
        //当不存在index
        } else {
            try {
                //调用无参构造,忽略index自动寻找
                this.parseState.push(new ConstructorArgumentEntry());
                //解析properties的值
                Object value = this.parsePropertyValue(ele, bd, (String)null);
                ValueHolder valueHolder = new ValueHolder(value);
                if (StringUtils.hasLength(typeAttr)) {
                    valueHolder.setType(typeAttr);
                }

                if (StringUtils.hasLength(nameAttr)) {
                    valueHolder.setName(nameAttr);
                }
                //保存到ValueHolder
                valueHolder.setSource(this.extractSource(ele));
                //保存至genericArgumentValue
                bd.getConstructorArgumentValues().addGenericArgumentValue(valueHolder);
            } finally {
                this.parseState.pop();
            }
        }

    }

解析properties属性

this.parsePropertyValue(ele, bd, (String)null)

  public Object parsePropertyValue(Element ele, BeanDefinition bd, @Nullable String propertyName) {
        String elementName = propertyName != null ? "<property> element for property '" + propertyName + "'" : "<constructor-arg> element";
        NodeList nl = ele.getChildNodes();
        Element subElement = null;
        //遍历子节点
        for(int i = 0; i < nl.getLength(); ++i) {
            Node node = nl.item(i);
            //跳过描述和元数据
            if (node instanceof Element && !this.nodeNameEquals(node, "description") && !this.nodeNameEquals(node, "meta")) {
                if (subElement != null) {
                    this.error(elementName + " must not contain more than one sub-element", ele);
                } else {
                    subElement = (Element)node;
                }
            }
        }
        //获取ref
        boolean hasRefAttribute = ele.hasAttribute("ref");
        //获取value
        boolean hasValueAttribute = ele.hasAttribute("value");
         //1.不允许既存在ref又存在value 
         //2.不允许ref或者value含有子元素
        if (hasRefAttribute && hasValueAttribute || (hasRefAttribute || hasValueAttribute) && subElement != null) {
            this.error(elementName + " is only allowed to contain either 'ref' attribute OR 'value' attribute OR sub-element", ele);
        }
        //如果存在ref
        if (hasRefAttribute) {
            //获取ref标签
            String refName = ele.getAttribute("ref");
            if (!StringUtils.hasText(refName)) {
                this.error(elementName + " contains empty 'ref' attribute", ele);
            }
            存入RuntimeBeanReference中
            RuntimeBeanReference ref = new RuntimeBeanReference(refName);
            ref.setSource(this.extractSource(ele));
            return ref;
            //如果存在value
        } else if (hasValueAttribute) {
            //存入TypedStringValue
            TypedStringValue valueHolder = new TypedStringValue(ele.getAttribute("value"));
            valueHolder.setSource(this.extractSource(ele));
            return valueHolder;
        } else if (subElement != null) {
            //如果存在子元素,则解析子元素
            return this.parsePropertySubElement(subElement, bd);
        } else {
            //如果不存在ref和value 直接报错
            this.error(elementName + " must specify a ref or value", ele);
            return null;
        }
    }

constructor-arg标签示例:

<?xml version="1.0" encoding="UTF-8"?>
<beans  xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="student" class="com.sgcc.bean.Student">
      <constructor-arg index="0" name="name" value="小黑"/>
      <constructor-arg index="1" name="age" value="18"/>
  </bean>
</beans>

解析子元素

parsePropertySubElement

public Object parsePropertySubElement(Element ele, @Nullable BeanDefinition bd, @Nullable String defaultValueType) {
        //自定义标签解析
        if (!this.isDefaultNamespace((Node)ele)) {
            return this.parseNestedCustomElement(ele, bd);
        //如果是bean标签
        } else if (this.nodeNameEquals(ele, "bean")) {
            BeanDefinitionHolder nestedBd = this.parseBeanDefinitionElement(ele, bd);
            if (nestedBd != null) {
                nestedBd = this.decorateBeanDefinitionIfRequired(ele, nestedBd, bd);
            }

            return nestedBd;
        //解析ref
        } else if (this.nodeNameEquals(ele, "ref")) {
            //获取bean属性
            String refName = ele.getAttribute("bean");
            boolean toParent = false;
            //如果存在父引用
            if (!StringUtils.hasLength(refName)) {
                //获取父bean属性
                refName = ele.getAttribute("parent");
                toParent = true;
                if (!StringUtils.hasLength(refName)) {
                    this.error("'bean' or 'parent' is required for <ref> element", ele);
                    return null;
                }
            }

            if (!StringUtils.hasText(refName)) {
                this.error("<ref> element contains empty target attribute", ele);
                return null;
            } else {
                //保存RuntimeBeanReference
                RuntimeBeanReference ref = new RuntimeBeanReference(refName, toParent);
                ref.setSource(this.extractSource(ele));
                return ref;
            }
        //解析idref标签
        } else if (this.nodeNameEquals(ele, "idref")) {
            return this.parseIdRefElement(ele);
        //解析value
        } else if (this.nodeNameEquals(ele, "value")) {
            return this.parseValueElement(ele, defaultValueType);
        //解析空值
        } else if (this.nodeNameEquals(ele, "null")) {
            TypedStringValue nullHolder = new TypedStringValue((String)null);
            nullHolder.setSource(this.extractSource(ele));
            return nullHolder;
        //解析array
        } else if (this.nodeNameEquals(ele, "array")) {
            return this.parseArrayElement(ele, bd);
        //解析list
        } else if (this.nodeNameEquals(ele, "list")) {
            return this.parseListElement(ele, bd);
        //解析set
        } else if (this.nodeNameEquals(ele, "set")) {
            return this.parseSetElement(ele, bd);
        //解析map
        } else if (this.nodeNameEquals(ele, "map")) {
            return this.parseMapElement(ele, bd);
        //解析props
        } else if (this.nodeNameEquals(ele, "props")) {
            return this.parsePropsElement(ele);
        } else {
            this.error("Unknown property sub-element: [" + ele.getNodeName() + "]", ele);
            return null;
        }
    }

解析properties元素

properties标签示例

<bean id="test" class="TestClass">
    <property name="teatStr"><value>aaa</value>
    </property>
</bean>

<bean id="test2" class="TestClass">
    <property name="L">
        <list>
            <value>aaa</value>
            <value>bbb</value>            
        </list>
    </property>
</bean>

this.parsePropertyElements(ele, bd)

this.parsePropertyElement((Element)node, bd)

public void parsePropertyElement(Element ele, BeanDefinition bd) {
        //获取name属性
        String propertyName = ele.getAttribute("name");
        if (!StringUtils.hasLength(propertyName)) {
            this.error("Tag 'property' must have a 'name' attribute", ele);
        } else {
            this.parseState.push(new PropertyEntry(propertyName));

            try {
                //不允许对同一属性多次配置
                if (!bd.getPropertyValues().contains(propertyName)) {
                    //解析值
                    Object val = this.parsePropertyValue(ele, bd, propertyName);
                    PropertyValue pv = new PropertyValue(propertyName, val);
                    //解析元数据
                    this.parseMetaElements(ele, pv);
                    pv.setSource(this.extractSource(ele));
                    //保存PropertyValue中
                    bd.getPropertyValues().addPropertyValue(pv);
                    return;
                }

                this.error("Multiple 'property' definitions for property '" + propertyName + "'", ele);
            } finally {
                this.parseState.pop();
            }

        }
    }

解析qualifier元素

qualifier标签示例

<bean id="test2" class="TestClass">
    <qualifier type="org.Springframework.beans.factory.annotation.Qualifier" value="gf"/></qualifier>
</bean>

this.parseQualifierElements(ele, bd)

public void parseQualifierElement(Element ele, AbstractBeanDefinition bd) {
        //获取type元素
        String typeName = ele.getAttribute("type");
        if (!StringUtils.hasLength(typeName)) {
            this.error("Tag 'qualifier' must have a 'type' attribute", ele);
        } else {
            this.parseState.push(new QualifierEntry(typeName));

            try {
                //保存至AutowireCandidateQualifier
                AutowireCandidateQualifier qualifier = new AutowireCandidateQualifier(typeName);
                qualifier.setSource(this.extractSource(ele));
                //获取value属性
                String value = ele.getAttribute("value");
                if (StringUtils.hasLength(value)) {
                    //存入AutowireCandidateQualifier
                    qualifier.setAttribute("value", value);
                }
                //获取子节点
                NodeList nl = ele.getChildNodes();
                //遍历
                for(int i = 0; i < nl.getLength(); ++i) {
                    Node node = nl.item(i);
                    if (this.isCandidateElement(node) && this.nodeNameEquals(node, "attribute")) {
                        Element attributeEle = (Element)node;
                        //获取key属性
                        String attributeName = attributeEle.getAttribute("key");
                        //获取value属性
                        String attributeValue = attributeEle.getAttribute("value");
                        //必须存在key和value
                        if (!StringUtils.hasLength(attributeName) || !StringUtils.hasLength(attributeValue)) {
                            this.error("Qualifier 'attribute' tag must have a 'name' and 'value'", attributeEle);
                            return;
                        }
                        //通过attributeName和attributeValue构建BeanMetadataAttribute
                        BeanMetadataAttribute attribute = new BeanMetadataAttribute(attributeName, attributeValue);
                        attribute.setSource(this.extractSource(attributeEle));
                        //存入qualifier
                        qualifier.addMetadataAttribute(attribute);
                    }
                }
            
                bd.addQualifier(qualifier);
            } finally {
                this.parseState.pop();
            }
        }
    }

至此我们已经完成了配置文件XML转换为GenericBeanDefinition,也就是说XML的所有配置都在GenericBeanDefinition找到对应的属性,但是更为详细的信息存储于AbstractBeanDefinition中,现在我们一起来看看AbstractBeanDefinition到底是何方神圣

AbstractBeanDefinition

public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor implements BeanDefinition, Cloneable {
    public static final String SCOPE_DEFAULT = "";
    public static final int AUTOWIRE_NO = 0;
    public static final int AUTOWIRE_BY_NAME = 1;
    public static final int AUTOWIRE_BY_TYPE = 2;
    public static final int AUTOWIRE_CONSTRUCTOR = 3;
    /** @deprecated */
    @Deprecated
    public static final int AUTOWIRE_AUTODETECT = 4;
    public static final int DEPENDENCY_CHECK_NONE = 0;
    public static final int DEPENDENCY_CHECK_OBJECTS = 1;
    public static final int DEPENDENCY_CHECK_SIMPLE = 2;
    public static final int DEPENDENCY_CHECK_ALL = 3;
    public static final String INFER_METHOD = "(inferred)";
    //bean的class对象或者类的全限定名 对应bean属性class
    @Nullable
    private volatile Object beanClass;
    //bean的作用域 对应bean属性scope
    @Nullable
    private String scope;
    //是否抽象标识 对应bean属性abstract
    private boolean abstractFlag;
    //是否为懒加载 对应bean属性lazy-init
    @Nullable
    private Boolean lazyInit;
    //注入模式 对应bean属性autowire
    private int autowireMode;
    //依赖检查
    private int dependencyCheck;
    //这里只会存放<bean/>标签的depends-on属性或是@DependsOn注解的值,对应bean属性depends-on
    @Nullable
    private String[] dependsOn;
    //当该属性设置为false时,这样容器在查找自动装配的对象时,
    //将不考虑该bean,即他不会被考虑作为其他bean自动装配的候选者,但是该bean本身
    //还是可以使用自动装配来注入其他bean的
    //对应bean属性autowire-candidate
    private boolean autowireCandidate;
    //当自动装配出现多个bean候选者时,将作为首选者,对应bean属性primary
    private boolean primary;
    //用于记录Qualifier,对应子元素qualifier
    private final Map<String, AutowireCandidateQualifier> qualifiers;
    
    @Nullable
    private Supplier<?> instanceSupplier;
    //允许访问非公开的构造器和方法
    private boolean nonPublicAccessAllowed;
    //指定解析构造函数的模式,是宽松还是严格
    private boolean lenientConstructorResolution;
    //工程类名 对应属性bean-factory
    @Nullable
    private String factoryBeanName;
    //工厂方法名 对应属性factory-method
    @Nullable 
    private String factoryMethodName;
    //记录构造函数对应属性,对应bean属性constructor-arg
    @Nullable
    private ConstructorArgumentValues constructorArgumentValues;
    //普通属性集合
    @Nullable
    private MutablePropertyValues propertyValues;
    //存储lookup-method replaced-method
    private MethodOverrides methodOverrides;
    //初始方法 对应bean属性init-method
    @Nullable
    private String initMethodName;
    //销毁方法 对应bean属性destroy-method
    @Nullable
    private String destroyMethodName;
    //是否强制执行init方法
    private boolean enforceInitMethod;
    //是否执行destroy方法
    private boolean enforceDestroyMethod;
    //是否是合成类(是不是应用自定义的,例如生成AOP代理时,会用到某些辅助类,
    //这些辅助类不是应用自定义的,这个就是合成类)
    private boolean synthetic;
    //Bean的角色,为用户自定义Bean
    private int role;
    //bean信息描述
    @Nullable
    private String description;
    //bean定义的资源
    @Nullable
    private Resource resource;
//省略
}

lenientConstructorResolution

总的来说,AbstractBeanDefinition保存的属性包括:

  1. Bean的描述信息(例如是否是抽象类、是否单例)

  1. depends-on属性(String类型,不是Class类型)

  1. 自动装配的相关信息

  1. init函数、destroy函数的名字(String类型)

  1. 工厂方法名、工厂类名(String类型,不是Class类型)

  1. 构造函数形参的值

  1. 被IOC容器覆盖的方法

  1. Bean的属性以及对应的值(在初始化后会进行填充)

好了,到此为止,我们已经分析了Spring默认bean标签的整体解析过程,下一步就是Spring对于bean进行进一步的装饰

装饰Bean

decorateBeanDefinitionIfRequired

 public BeanDefinitionHolder decorateBeanDefinitionIfRequired(Element ele, BeanDefinitionHolder originalDef, @Nullable BeanDefinition containingBd) {
        BeanDefinitionHolder finalDefinition = originalDef;
        //获取所有的自定义属性
        NamedNodeMap attributes = ele.getAttributes();
        //遍历自定义属性,装饰需要装饰的属性
        for(int i = 0; i < attributes.getLength(); ++i) {
            Node node = attributes.item(i);
            finalDefinition = this.decorateIfRequired(node, finalDefinition, containingBd);
        }
        //获取所有的子节点
        NodeList children = ele.getChildNodes();
        //遍历所有的子节点,装饰需要装饰的子节点
        for(int i = 0; i < children.getLength(); ++i) {
            Node node = children.item(i);
            if (node.getNodeType() == 1) {
                finalDefinition = this.decorateIfRequired(node, finalDefinition, containingBd);
            }
        }

        return finalDefinition;
    }

decorateIfRequired

public BeanDefinitionHolder decorateIfRequired(Node node, BeanDefinitionHolder originalDef, @Nullable BeanDefinition containingBd) {
        //获取自定义属性或者子节点的命名空间
        String namespaceUri = this.getNamespaceURI(node);
        //如果是Spring默认命名空间则不处理
        if (namespaceUri != null && !this.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/")) {
                this.error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", node);
            } else if (this.logger.isDebugEnabled()) {
                this.logger.debug("No Spring NamespaceHandler found for XML schema namespace [" + namespaceUri + "]");
            }
        }

        return originalDef;
    }

注册Bean

registerBeanDefinition

   public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {
        //获取beanName
        String beanName = definitionHolder.getBeanName();
        //根据beanName注册Bean
        registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
        //获取别名
        String[] aliases = definitionHolder.getAliases();
        if (aliases != null) {
            String[] var4 = aliases;
            int var5 = aliases.length;

            for(int var6 = 0; var6 < var5; ++var6) {
                String alias = var4[var6];
                //根据别名注册Bean
                registry.registerAlias(beanName, alias);
            }
        }

    }

根据BeanName注册

registerBeanDefinition

public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {
        Assert.hasText(beanName, "Bean name must not be empty");
        Assert.notNull(beanDefinition, "BeanDefinition must not be null");
        //判断当前的bean属性是否是AbstractBeanDefinition类型
        if (beanDefinition instanceof AbstractBeanDefinition) {
            try {
                //注册前最后一次校验
                //主要校验的是overrideMethod校验,判断methodOverride是否与
                //factoryMethod并存,或者methodOverride对应的方法不存在
                ((AbstractBeanDefinition)beanDefinition).validate();
            } catch (BeanDefinitionValidationException var8) {
                throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", var8);
            }
        }
        //根据beanName在容器查找实例
        BeanDefinition existingDefinition = (BeanDefinition)this.beanDefinitionMap.get(beanName);
        if (existingDefinition != null) {
            //判断是否允许覆盖
            if (!this.isAllowBeanDefinitionOverriding()) {
                throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
            }
            //不清楚
            if (existingDefinition.getRole() < beanDefinition.getRole()) {
                if (this.logger.isInfoEnabled()) {
                    this.logger.info("Overriding user-defined bean definition for bean '" + beanName + "' with a framework-generated bean definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]");
                }
            } else if (!beanDefinition.equals(existingDefinition)) {
                if (this.logger.isDebugEnabled()) {
                    this.logger.debug("Overriding bean definition for bean '" + beanName + "' with a different definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]");
                }
            } else if (this.logger.isTraceEnabled()) {
                this.logger.trace("Overriding bean definition for bean '" + beanName + "' with an equivalent definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]");
            }
            //以beanName为key,beanDefinition为value放入map容器中
            this.beanDefinitionMap.put(beanName, beanDefinition);
        //容器中不存在该bean实例
        } else {
            //判断是否已经创建过
            //已创建
            if (this.hasBeanCreationStarted()) {
                //考虑并发情况,保证线程安全
                synchronized(this.beanDefinitionMap) {
                    //覆盖同名的beanDefinition
                    this.beanDefinitionMap.put(beanName, beanDefinition);
                    //创建beanDefinitionNames+1的集合
                    List<String> updatedDefinitions = new ArrayList(this.beanDefinitionNames.size() + 1);
                    //将beanDefinitionNames存入updatedDefinitions中
                    updatedDefinitions.addAll(this.beanDefinitionNames);
                    //添加增量的bean
                    updatedDefinitions.add(beanName);
                    //更新所有的beanDefinitionNames
                    this.beanDefinitionNames = updatedDefinitions;
                    //从单例BeanName列表中移除该beanName,
                    //如果this.manualSingletonNames中contains该beanName,执行remove操作
                    this.removeManualSingletonName(beanName);
                }
            //未创建
            } else {
                //放入beanDefinitionMap中
                this.beanDefinitionMap.put(beanName, beanDefinition);
                //在beanDefinitionNames添加beanName
                this.beanDefinitionNames.add(beanName);
                this.removeManualSingletonName(beanName);
            }
            // 将注册期间冻结的beanName列表清除,一个volatile修饰的String数组,
            //Spring内存优化操作
            this.frozenBeanDefinitionNames = null;
        }
        //判断是否存在beanDefinition并且存在Ioc容器中
        if (existingDefinition == null && !this.containsSingleton(beanName)) {
            if (this.isConfigurationFrozen()) {
                this.clearByTypeCache();
            }
        } else {
            //清除缓存
            this.resetBeanDefinition(beanName);
        }

    }

根据别名注册

registerAlias

    public void registerAlias(String name, String alias) {
        Assert.hasText(name, "'name' must not be empty");
        Assert.hasText(alias, "'alias' must not be empty");
        //考虑并发情况,保证线程安全
        synchronized(this.aliasMap) {
            //如果别名与beanName一样,则删除别名
            if (alias.equals(name)) {
                this.aliasMap.remove(alias);
                if (this.logger.isDebugEnabled()) {
                    this.logger.debug("Alias definition '" + alias + "' ignored since it points to same name");
                }
            } else {
                //获取别名得到注册名称
                String registeredName = (String)this.aliasMap.get(alias);
                if (registeredName != null) {
                    if (registeredName.equals(name)) {
                        return;
                    }
                    //如果不允许覆盖,跑出异常
                    if (!this.allowAliasOverriding()) {
                        throw new IllegalStateException("Cannot define alias '" + alias + "' for name '" + name + "': It is already registered for name '" + registeredName + "'.");
                    }

                    if (this.logger.isDebugEnabled()) {
                        this.logger.debug("Overriding alias '" + alias + "' definition for registered name '" + registeredName + "' with new target name '" + name + "'");
                    }
                }
                //校验别名环
                //不允许出现:A->B   A->C->B这种情况
                this.checkForAliasCircle(name, alias);
                //放入map容器中
                this.aliasMap.put(alias, name);
                if (this.logger.isTraceEnabled()) {
                    this.logger.trace("Alias definition '" + alias + "' registered for name '" + name + "'");
                }
            }

        }
    }

最后通知监听器,注册完成

至此我们分析了Spring是如何解析XML中的默认Bean标签,并获取对应的属性,再进行装饰和

注册,下面我们来总结一下

总结

  1. 解析标签

  1. 解析bean标签

  1. 解析元数据标签

  1. 解析lookup-method标签

  1. 解析constructor-arg标签

  1. 解析properties标签

  1. 解析qualifier

  1. 将删除解析的内容全部存入AbstractBeanDefinition对应的属性中

  1. 如果某些自定义标签或者子节点需要装饰,则进行装饰

  1. 注册bean

  1. 根据beanName进行注册

  1. 根据别名进行注册

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值