美文网首页
spring源码分析1----读xml文件

spring源码分析1----读xml文件

作者: 天一阁图书管理员 | 来源:发表于2020-02-17 14:09 被阅读0次

    作者:shihuaping0918@163.com转载请注明作者

    spring是怎么读取xml配置文件的,又是怎么把xml里的bean装载进去的呢,这就是本篇文章的内容。配置读取使用的类是ClassPathXmlApplicationContext,这个类的继承层次如下:

    可以看出层次还是比较多的,ClassPathXmlApplicationContext其实只是一个壳子,方便使用的时候传递一些参数,其中就包括了xml文件的路径,xml路径可以有多个,最终填充在configResources或者调用setConfigLocations——传递到了AbstractRefreshableApplicationContext。这个类只有一个动作,就是refresh。这个refresh是在AbstractApplicationContext里实现的,这个方法很复杂,涉及的内容比较多。后面再慢慢讲。不论路径怎么传递,反正都是要调用refresh的。

    继续分析之前,先说明一下各个类到底是干什么的,有个大概印象,这样讲到某些功能的时候,可以大概推测是在哪个类里。ClassPathXmlApplicationContext是个配参数的类,方便用户传参。AbstractXmlApplicationContext实现的功能是读xml文件。AbstractRefreshableConfigApplicationContext实现的是一些属性配置功能,比如xml文件路径什么的。AbstractApplicationContext是具体干活的,承担的任务非常重。再往下就没什么可讲的了。这样很好的实现了分离,每一层做自己的事,通用的功能剥离出去了。但是读代码的时候,就很不顺利了,在印象没有建立起来之前,感觉是在绕迷宫。

    AbstractRefreshableConfigApplicationContext这个类,有一个方法

    public void setConfigLocations(@Nullable String... locations) {
         if (locations != null) {
             Assert.noNullElements(locations, "Config locations must not be null");
             this.configLocations = new String[locations.length];
             for (int i = 0; i < locations.length; i++) {
                  this.configLocations[i] = resolvePath(locations[i]).trim();
            }
        }
       else {
            this.configLocations = null;
        }
    }
    

    这个setConfigLocations在ClassPathXmlApplicationContext中被调用过,实际上就是配一下xml文件的路径。xml文件路径的传出是在

    @Nullable
    protected String[] getConfigLocations() {
        return (this.configLocations != null ? this.configLocations : getDefaultConfigLocations());
    }
    

    这个getConfigLocations是在AbstractXmlApplicationContext中调用的

    protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
       Resource[] configResources = getConfigResources();
        if (configResources != null) {
            reader.loadBeanDefinitions(configResources);
        }
        String[] configLocations = getConfigLocations();
        if (configLocations != null) {
             reader.loadBeanDefinitions(configLocations);
        }
    }
    

    注意看AbstractXmlApplicationContext这个loadBeanDefinitions方法,它首先是调用了getConfigResources,这个方法实际是在ClassPathXmlApplicationContext中实现的。而后一个getConfigLocations是在AbstractRefreshableConfigApplicationContext中实现的。到了这里ClassPathXmlApplicationContext和AbstractRefreshableConfigApplicationContext就算分析完成了。

    下面再看看AbstractXmlApplicationContext,这个类前面就讲过了,是加载xml用的,而它要加载的xml文件路径是来自于ClassPathXmlApplicationContext和AbstractRefreshableConfigApplicationContext。下面看看加载xml的代码。

    protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
        Resource[] configResources = getConfigResources();
        if (configResources != null) {
            reader.loadBeanDefinitions(configResources);
        }
        String[] configLocations = getConfigLocations();
        if (configLocations != null) {
            reader.loadBeanDefinitions(configLocations);
        }
    }
    

    这段代码之前已经贴过了,可以看到,工作都是由reader这个参数来完成的。到了这里,休息一下,下一篇继续寻找这个reader是哪来的,它做了什么。

    相关文章

      网友评论

          本文标题:spring源码分析1----读xml文件

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