美文网首页
深入理解SpringBoot(二) 加载配置文件

深入理解SpringBoot(二) 加载配置文件

作者: skyguard | 来源:发表于2018-11-14 11:14 被阅读0次

    下面我们来说一下SpringBoot是怎么加载配置文件的。我们先来看一下SpringApplication的setInitializers方法

    public void setInitializers(
            Collection<? extends ApplicationContextInitializer<?>> initializers) {
        this.initializers = new ArrayList<>();
        this.initializers.addAll(initializers);
    }
    

    然后再看一下ConfigFileApplicationContextInitializer这个类

    public void initialize(ConfigurableApplicationContext applicationContext) {
        new ConfigFileApplicationListener() {
            public void apply() {
                addPropertySources(applicationContext.getEnvironment(),
                        applicationContext);
                addPostProcessors(applicationContext);
            }
        }.apply();
    }
    

    再看一下ConfigFileApplicationListener这个类

      public void postProcessEnvironment(ConfigurableEnvironment environment,
            SpringApplication application) {
        addPropertySources(environment, application.getResourceLoader());
    }
    

    加载PropertySource,就是配置文件

    protected void addPropertySources(ConfigurableEnvironment environment,
            ResourceLoader resourceLoader) {
        RandomValuePropertySource.addToEnvironment(environment);
        new Loader(environment, resourceLoader).load();
    }
    

    再到load方法

    public void load() {
            this.profiles = new LinkedList<>();
            this.processedProfiles = new LinkedList<>();
            this.activatedProfiles = false;
            this.loaded = new LinkedHashMap<>();
            initializeProfiles();
            while (!this.profiles.isEmpty()) {
                Profile profile = this.profiles.poll();
                if (profile != null && !profile.isDefaultProfile()) {
                    addProfileToEnvironment(profile.getName());
                }
                load(profile, this::getPositiveProfileFilter,
                        addToLoaded(MutablePropertySources::addLast, false));
                this.processedProfiles.add(profile);
            }
            resetEnvironmentProfiles(this.processedProfiles);
            load(null, this::getNegativeProfileFilter,
                    addToLoaded(MutablePropertySources::addFirst, true));
            addLoadedPropertySources();
        }
    

    再进去看一下

    private void load(Profile profile, DocumentFilterFactory filterFactory,
                DocumentConsumer consumer) {
            getSearchLocations().forEach((location) -> {
                boolean isFolder = location.endsWith("/");
                Set<String> names = isFolder ? getSearchNames() : NO_SEARCH_NAMES;
                names.forEach(
                        (name) -> load(location, name, profile, filterFactory, consumer));
            });
        }
    

    取到所有的配置文件的存放位置,再遍历出来一个一个的处理

    private void load(String location, String name, Profile profile,
                DocumentFilterFactory filterFactory, DocumentConsumer consumer) {
            if (!StringUtils.hasText(name)) {
                for (PropertySourceLoader loader : this.propertySourceLoaders) {
                    if (canLoadFileExtension(loader, location)) {
                        load(loader, location, profile,
                                filterFactory.getDocumentFilter(profile), consumer);
                        return;
                    }
                }
            }
            Set<String> processed = new HashSet<>();
            for (PropertySourceLoader loader : this.propertySourceLoaders) {
                for (String fileExtension : loader.getFileExtensions()) {
                    if (processed.add(fileExtension)) {
                        loadForFileExtension(loader, location + name, "." + fileExtension,
                                profile, filterFactory, consumer);
                    }
                }
            }
        }
    

    调用PropertySourceLoader来加载配置文件
    看一下PropertiesPropertySourceLoader这个类

    public List<PropertySource<?>> load(String name, Resource resource)
            throws IOException {
        Map<String, ?> properties = loadProperties(resource);
        if (properties.isEmpty()) {
            return Collections.emptyList();
        }
        return Collections
                .singletonList(new OriginTrackedMapPropertySource(name, properties));
    }
    

    再到loadProperties方法

    private Map<String, ?> loadProperties(Resource resource) throws IOException {
        String filename = resource.getFilename();
        if (filename != null && filename.endsWith(XML_FILE_EXTENSION)) {
            return (Map) PropertiesLoaderUtils.loadProperties(resource);
        }
        return new OriginTrackedPropertiesLoader(resource).load();
    }
    

    把properties配置文件加载进来,放到map里返回
    那么我们一般默认的配置文件是application.properties,这个是在哪里配置的呢,我们来看一下ConfigFileApplicationListener有一个属性值DEFAULT_NAMES

    private static final String DEFAULT_NAMES = "application";
    

    在getSearchNames方法里添加进去

    private Set<String> getSearchNames() {
            if (this.environment.containsProperty(CONFIG_NAME_PROPERTY)) {
                String property = this.environment.getProperty(CONFIG_NAME_PROPERTY);
                return asResolvedSet(property, null);
            }
            return asResolvedSet(ConfigFileApplicationListener.this.names, DEFAULT_NAMES);
        }
    

    SpringBoot的加载配置文件的过程就分析到这里了。

    相关文章

      网友评论

          本文标题:深入理解SpringBoot(二) 加载配置文件

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