spring源码四

spring默认标签的解析

/**

     * Process the given bean element, parsing the bean definition

     * and registering it with the registry.

     */

    protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {

        BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);

        if (bdHolder != null) {

            bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);

            try {

                // Register the final decorated instance.

                BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());

            }

            catch (BeanDefinitionStoreException ex) {

                getReaderContext().error("Failed to register bean definition with name '" +

                        bdHolder.getBeanName() + "'", ele, ex);

            }

            // Send registration event.

            getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));

        }

    }

1.    首先委托BeanDefinitionDelegate类的parseBeanDefinitionElement方法进行元素解析,返回BeanDefinitionHolder类型的实例bdHolder,经过这个方法后,bdHolder实例已经包含我们配置文件的各种属性了,例如class,name,id,alias之类的属性

2.    当返回的bdHolder不为空的情况下若存在默认标签子节点再有自定义属性,还需要再次对自定义标签进行解析

3.    解析完成后,需要对解析后的bdHolder进行注册,同样,注册委托给了BeanDefinitionReaderUtils的registerBeanDefinition方法

4.    最后发出响应事件,通知相关的监听器,这个bean已经加载完成了

131213_lYl6_1866807.png

1.解析BeanDefinition

BeanDefinitionHolder bdHolder=delegate.pareseBeanDefinitionElement(ele)

public class BeanDefinitionParserDelegate {

    public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {

        return parseBeanDefinitionElement(ele, null);

}

public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {

        String id = ele.getAttribute(ID_ATTRIBUTE);

        String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);

 

        List<String> aliases = new ArrayList<>();

        if (StringUtils.hasLength(nameAttr)) {

            String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);

            aliases.addAll(Arrays.asList(nameArr));

        }

 

        String beanName = id;

        if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {

            beanName = aliases.remove(0);

            if (logger.isDebugEnabled()) {

                logger.debug("No XML 'id' specified - using '" + beanName +

                        "' as bean name and " + aliases + " as aliases");

            }

        }

 

        if (containingBean == null) {

            checkNameUniqueness(beanName, aliases, ele);

        }

 

        AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);

        if (beanDefinition != null) {

            if (!StringUtils.hasText(beanName)) {

                try {

                    if (containingBean != null) {

                        beanName = BeanDefinitionReaderUtils.generateBeanName(

                                beanDefinition, this.readerContext.getRegistry(), true);

                    }

                    else {

                        beanName = this.readerContext.generateBeanName(beanDefinition);

                        // Register an alias for the plain bean class name, if still possible,

                        // if the generator returned the class name plus a suffix.

                        // This is expected for Spring 1.2/2.0 backwards compatibility.

                        String beanClassName = beanDefinition.getBeanClassName();

                        if (beanClassName != null &&

                                beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&

                                !this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {

                            aliases.add(beanClassName);

                        }

                    }

                    if (logger.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);

            return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);

        }

 

        return null;

}

}

1.提取元素中的id,name属性

2.进一步解析其他所有属性并统一封装至GenericBeanDefinition类型的实例中

 

3.如果检测到bean没有指定beanName,那么用默认规则为此Bean生成beanName

4.将获取的信息封装到BeanDefinitionHolder实例中

第二步中对标签其他属性解析

public AbstractBeanDefinition parseBeanDefinitionElement(

            Element ele, String beanName, BeanDefinition containingBean) {

 

        this.parseState.push(new BeanEntry(beanName));

 

        String className = null;

        if (ele.hasAttribute(CLASS_ATTRIBUTE)) {

            className = ele.getAttribute(CLASS_ATTRIBUTE).trim();

        }

 

        try {

            String parent = null;

            if (ele.hasAttribute(PARENT_ATTRIBUTE)) {

                parent = ele.getAttribute(PARENT_ATTRIBUTE);

            }

            AbstractBeanDefinition bd = createBeanDefinition(className, parent);

 

            parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);

            bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));

 

            parseMetaElements(ele, bd);

            parseLookupOverrideSubElements(ele, bd.getMethodOverrides());

            parseReplacedMethodSubElements(ele, bd.getMethodOverrides());

 

            parseConstructorArgElements(ele, bd);

            parsePropertyElements(ele, bd);

            parseQualifierElements(ele, bd);

 

            bd.setResource(this.readerContext.getResource());

            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;

}

 

 

解析标签结束

转载于:https://my.oschina.net/iioschina/blog/830873

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值