多个库的配置目录中的多个 application.yaml

mutliple application.yaml in config directory of mutliple libraries

我正在开发多个微型库(外部 jar),我需要让它们添加它们的 application.yml 以便它们可以被 1 spring 引导发现,将它们作为依赖项。这对第一个库工作得很好,但似乎只要我有超过 1 个,第二个就会被忽略(spring 引导覆盖第一个因为类路径冲突?)。

执行此操作的正确方法是什么?

我建议您将它们重命名为更具体,例如 abc.ymlabc-prod.yml(适用于您的所有阶段)。然后,您可以创建一个 EnvironmentPostProcessor 来读取您的 YAML 文件并将所有属性添加到上下文中。这是一个 EnvironmentPostProcessor 的工作示例,它确实做到了这一点:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.boot.env.YamlPropertySourceLoader;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.ClassPathResource;

import java.io.IOException;
import java.util.Arrays;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Stream;

import static java.util.function.Predicate.not;

public class MyPropertiesEnvironmentPostProcessor implements EnvironmentPostProcessor {

    private static final Set<String> KNOWN_STAGES = Set.of("local", "dev", "ref", "abn", "prod");
    private final YamlPropertySourceLoader loader = new YamlPropertySourceLoader();

    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
        Stream.concat(Arrays.stream(environment.getActiveProfiles())
                                .map(String::toLowerCase)
                                .filter(KNOWN_STAGES::contains),
                        Stream.of(""))
                .map(String::toLowerCase)
                .distinct()
                .map(this::loadYaml)
                .forEach(environment.getPropertySources()::addLast);
    }

    private PropertySource<?> loadYaml(final String stage) {
        final String stageSuffix = Optional.ofNullable(stage).filter(not(String::isEmpty)).map("-"::concat).orElse("");
        final ClassPathResource configFile = new ClassPathResource(String.format("abc%s.yml", stageSuffix));
        if (!configFile.exists())
            throw new IllegalArgumentException(String.format("Config file %s does not exist", configFile));
        try {
            return loader.load(String.format("abc%s", stageSuffix), configFile).get(0);
        } catch (IOException e) {
            throw new IllegalStateException(String.format("Failed to load %s", configFile), e);
        }
    }

}

注意属性是用addLast方法添加的。您还可以使用 addFirst,具体取决于您是否希望您的属性能够被使用您的库的 Spring 启动应用程序覆盖,或者您是否希望覆盖 application.yml 的值34=]启动应用程序。

确保在您注册 EnvironmentPostProcessor 的库的 src/main/resources/META-INF 目录中创建一个 spring.factories 文件,以便使用您的 Spring 启动应用程序图书馆知道这个 EnvironmentPostProcessor 需要被调用:

org.springframework.boot.env.EnvironmentPostProcessor=\
com.myproject.MyPropertiesEnvironmentPostProcessor

这篇 Baeldung article 也是一本好书。