【Quarkus】quarkus框架获取配置的几种方式

分析

翻源码可以发现

读取接口

org.eclipse.microprofile.config.spi.ConfigSourceProvider

实现类

// 从环境变量中读取
io.smallrye.config.DotEnvConfigSourceProvider
// classpath中读取application.properties
io.quarkus.runtime.configuration.ApplicationPropertiesConfigSourceLoader.InClassPath
// 文件系统中读取 System.getProperty("user.dir"), "config", "application.properties"
io.quarkus.runtime.configuration.ApplicationPropertiesConfigSourceLoader.InFileSystem

这个是获取配置源的代码,debug模式时可以发现builder.getSourceProviders()包含上面三者

io.smallrye.config.SmallRyeConfig.ConfigSources#buildSources

        private static List<ConfigSource> buildSources(final SmallRyeConfigBuilder builder) {
            List<ConfigSource> sourcesToBuild = new ArrayList<>(builder.getSources());
            // 提供配置的来源: 环境变量、classpath、fileSystem
            for (ConfigSourceProvider sourceProvider : builder.getSourceProviders()) {
                // 从来源中获取配置源,如从classpath中获取所有application.properties作为ConfigSource实例供后续获取配置
                for (ConfigSource configSource : sourceProvider.getConfigSources(builder.getClassLoader())) {
                    sourcesToBuild.add(configSource);
                }
            }

            if (builder.isAddDiscoveredSources()) {
                sourcesToBuild.addAll(builder.discoverSources());
            }
            if (builder.isAddDefaultSources()) {
                sourcesToBuild.addAll(builder.getDefaultSources());
            }
            sourcesToBuild.add(new DefaultValuesConfigSource(builder.getDefaultValues()));

            return sourcesToBuild;
        }

结论

以下就是获取到配置源后,获取某一项配置的代码

io.smallrye.config.SmallRyeConfigSources#getValue

    public ConfigValue getValue(final ConfigSourceInterceptorContext context, final String name) {
        // 前面获取到配置源为configSources,这是一个数组,所以就会有优先级
        for (int i = 0, configSourcesSize = configSources.size(); i < configSourcesSize; i++) {
            final ConfigValueConfigSource configSource = configSources.get(i);
            final ConfigValue configValue = configSource.getConfigValue(name);
            // 这里可以看到逻辑是一旦获取到配置就会立即返回,所以可以看出配置优先级是根据configSources的顺序来排的。
            // 如果单纯想要看优先级,打个debug断点在这就可以看到了
            if (configValue != null) {
                return configValue.from().withConfigSourcePosition(i).build();
            }
        }
        return null;
    }

configSources

附言

顺带说一下这个源码的切入点,为增加一个config拦截器,通过debug找栈找到的。

配置拦截器文档

posted @ 2023-12-14 15:42  小小记录本  阅读(84)  评论(0编辑  收藏  举报