美文网首页
2.1.1Spring源码解析——import标签的解析

2.1.1Spring源码解析——import标签的解析

作者: szhlcy | 来源:发表于2018-08-04 11:17 被阅读0次

直接看代码

protected void importBeanDefinitionResource(Element ele) {
         //获取Resource属性
        String location = ele.getAttribute(RESOURCE_ATTRIBUTE);
        //如果不存在Resource属性则不做任何处理
        if (!StringUtils.hasText(location)) {
            getReaderContext().error("Resource location must not be empty", ele);
            return;
        }
        //解析系统属性,格式如:“${user.dir}”
        // Resolve system properties: e.g. "${user.dir}"
        location = getEnvironment().resolveRequiredPlaceholders(location);

        Set<Resource> actualResources = new LinkedHashSet<Resource>(4);

        // Discover whether the location is an absolute or relative URI
        //判断Location是决定URI还是URL
        boolean absoluteLocation = false;
        try {
            absoluteLocation = ResourcePatternUtils.isUrl(location) || ResourceUtils.toURI(location).isAbsolute();
        }
        catch (URISyntaxException ex) {
            // cannot convert to an URI, considering the location relative
            // unless it is the well-known Spring prefix "classpath*:"
        }

        // Absolute or relative?
        //如果是绝对路径,则直接根据地址解析对应的配置
        if (absoluteLocation) {
            try {
                int importCount = getReaderContext().getReader().loadBeanDefinitions(location, actualResources);
                if (logger.isDebugEnabled()) {
                    logger.debug("Imported " + importCount + " bean definitions from URL location [" + location + "]");
                }
            }
            catch (BeanDefinitionStoreException ex) {
                getReaderContext().error(
                        "Failed to import bean definitions from URL location [" + location + "]", ele, ex);
            }
        }
        else {
            // No URL -> considering resource location as relative to the current file.
                        //todo.如果是相时地址则根据相对地址计算出绝对地址
            try {
                int importCount;
                  //前面提到Resource存在多个子类,而每个子类的createRelative方式实现都是不一样的,所以这里先使用子类的方法尝试
                Resource relativeResource = getReaderContext().getResource().createRelative(location);
                if (relativeResource.exists()) {
                    importCount = getReaderContext().getReader().loadBeanDefinitions(relativeResource);
                    actualResources.add(relativeResource);
                }
                else {
                  //如果解析不成功那么使用默认的ResourcePatternResolver进行解析
                    String baseLocation = getReaderContext().getResource().getURL().toString();
                    importCount = getReaderContext().getReader().loadBeanDefinitions(
                            StringUtils.applyRelativePath(baseLocation, location), actualResources);
                }
                if (logger.isDebugEnabled()) {
                    logger.debug("Imported " + importCount + " bean definitions from relative location [" + location + "]");
                }
            }
            catch (IOException ex) {
                getReaderContext().error("Failed to resolve current resource location", ele, ex);
            }
            catch (BeanDefinitionStoreException ex) {
                getReaderContext().error("Failed to import bean definitions from relative location [" + location + "]",
                        ele, ex);
            }
        }
              //解析完成之后通知监听器进行处理
        Resource[] actResArray = actualResources.toArray(new Resource[actualResources.size()]);
        getReaderContext().fireImportProcessed(location, actResArray, extractSource(ele));
    }

上面代码的主要步骤:
(1)获取resource属性所表示的路径
(2)解析路径中的系统属性,格式如"${user.dir}"
(3)判定location是绝对路径还是相对路径
(4)如果是绝对路径则递归调用bean的解析过程,进行另一次的解析
(5)如果是相对路径则计算出绝对路径并进行解析
(6)通知监听器,解析完成

相关文章

网友评论

      本文标题:2.1.1Spring源码解析——import标签的解析

      本文链接:https://www.haomeiwen.com/subject/hvopvftx.html