是否可以从 Maven 多模块项目的父模块中的配置文件夹加载 Spring-Boot 属性?

Is it possible to load Spring-Boot properties from config folder within parent module of a Maven multi-module project?

是否可以从多模块项目的父模块中的 config 文件夹加载多个 Spring-Boot .yml 配置文件?

因此,结构如下所示:

parent-module/
  pom.xml
  config/
    application-prd.yml
    application-dev.yml
  module1
    pom.xml
    src/main/resources/
      logback-spring.xml
      bootstrap.yml

这可能吗?怎么做到的?

所以,如果我从多模块项目的根文件夹执行,我会使用这个命令:

mvn -pl module1 spring-boot:run
   OR
mvn spring-boot:run

我希望 config 文件夹包含在类路径中?我正在尝试这样做,但没有让它发挥作用。我错过了什么吗?

我们知道这是真的:Child POMs inherit properties, dependencies, and plugin configurations from the parent. 但这不应该意味着 {parent}/config/application.yml 已经在类路径中了吗?

用于证明的示例项目:https://github.com/djangofan/spring-boot-maven-multi-module-example。觉得可以解决就clone修改一下吧

是的,有可能。

当您使用 -pl 时,Maven 将工作目录更改为模块的目录。所以它不再是具有 config/ 目录的根。

或者您可以重构您的 Maven 多模块设置,以便您可以打包通用 application.yml 文件并使用它们。我不推荐这样做,因为它有很多陷阱。

可能更容易使用 --spring.config-location

$ java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties

我目前无法测试它,但如果它不起作用,您可以随时尝试 -Dspring.config.locationSPRING_CONFIG_LOCATION 环境变量。

我发现了一个 customized way of doing it,我仍然认为它是 hack,如下所示,但我仍在寻找我的问题的实际答案(如果存在的话)。

@Slf4j
@SpringBootApplication
public class Application {

    private static String DEV_PROPS = "application-dev.properties";
    private static String PRD_PROPS = "application-prd.properties";
    private static String DEFAULT_PROPS = "application.properties";

    private static Path CONFIG = Paths.get(System.getProperty("user.dir"))
            .resolve(Paths.get(".."))
            .resolve("config");

    private static final String EXT_CONFIG_DIR = CONFIG.toString() + File.separator;

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Bean
    public PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        PropertySourcesPlaceholderConfigurer properties = new PropertySourcesPlaceholderConfigurer();
        Resource[] resources = new Resource[] {
                        new FileSystemResource(EXT_CONFIG_DIR + PRD_PROPS),
                        new FileSystemResource(EXT_CONFIG_DIR + DEV_PROPS),
                        new ClassPathResource(DEFAULT_PROPS)
                };
        log.info("Properties: " + Arrays.deepToString(resources));
        properties.setIgnoreResourceNotFound(true);
        properties.setLocations(resources);
        return properties;
    }

}

此方法的问题是必须更改配置以支持其他 environment profile names

无需编写代码。您可以为此使用 Exec Maven 插件。将插件添加到父模块:

<build>
  <plugins>
    <plugin>
      <groupId>org.codehaus.mojo</groupId>
      <artifactId>exec-maven-plugin</artifactId>
      <version>1.6.0</version>
      <configuration>
        <mainClass>PACKAGE.MODULE_MAIN_CLASS</mainClass>
        <arguments>
          <argument>--spring.profiles.active=dev</argument>
        </arguments>
      </configuration>
    </plugin>
  </plugins>
</build>

然后 运行 mvn install 一次,然后 mvn exec 每当您想启动应用程序时。

mvn exec:java -pl module1

有关多模块项目中 Maven 目标的更多信息,请查看此答案 。

另一种配置方法是这样的,它需要 workingDirectory 参数:

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <mainClass>com.example.Application</mainClass>
        <workingDirectory>${maven.multiModuleProjectDirectory}</workingDirectory>
        <arguments>
            <argument>--spring.profiles.active=dev</argument>
        </arguments>
    </configuration>
</plugin>

在这种情况下,执行:

mvn spring-boot:run -pl module1