多个库的配置目录中的多个 application.yaml
mutliple application.yaml in config directory of mutliple libraries
我正在开发多个微型库(外部 jar),我需要让它们添加它们的 application.yml 以便它们可以被 1 spring 引导发现,将它们作为依赖项。这对第一个库工作得很好,但似乎只要我有超过 1 个,第二个就会被忽略(spring 引导覆盖第一个因为类路径冲突?)。
执行此操作的正确方法是什么?
我建议您将它们重命名为更具体,例如 abc.yml
和 abc-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 也是一本好书。
我正在开发多个微型库(外部 jar),我需要让它们添加它们的 application.yml 以便它们可以被 1 spring 引导发现,将它们作为依赖项。这对第一个库工作得很好,但似乎只要我有超过 1 个,第二个就会被忽略(spring 引导覆盖第一个因为类路径冲突?)。
执行此操作的正确方法是什么?
我建议您将它们重命名为更具体,例如 abc.yml
和 abc-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 也是一本好书。