【问题标题】:Is it possible to load Spring-Boot properties from config folder within parent module of a Maven multi-module project?是否可以从 Maven 多模块项目的父模块中的配置文件夹加载 Spring-Boot 属性?
【发布时间】:2021-05-02 16:58:53
【问题描述】:

是否可以从多模块项目的父模块内的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。如果您认为可以解决,请克隆并修改。

【问题讨论】:

  • 如果在package 阶段使用maven-resources-plugin 将文件从parent 复制到module1 会怎样?

标签: spring-boot maven maven-3 multi-module


【解决方案1】:

无需编写代码。您可以为此使用 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 目标的更多信息,请查看此答案 https://stackoverflow.com/a/11091569/512667

另一种配置方式是这样,需要workingDirectory arg:

<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

【讨论】:

  • 感谢您的建议。我试过了,但没有用。这是我尝试过的分支:github.com/djangofan/spring-boot-maven-multi-module-example/…
  • @djangofan github URL 不可访问
  • 我的错,只需将配置文件参数附加到 mvn 命令: mvn exec:java -pl spring-boot-module -Dspring.profiles.active=dev
  • 是的,这行得通。我想我会给你赏金。谢谢你。此外,spring“默认配置文件”可以放在属性文件中而不是在命令行中,使执行更简单。我宁愿使用 spring-boot-maven-plugin 但很高兴知道这个解决方案有效。
  • 没问题。难道你的橡皮鸭不值得你承诺的赏金吗? ;-)
【解决方案2】:

是的,有可能。

当您使用-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 环境变量。

【讨论】:

  • 寻找一个不需要以任何方式覆盖类路径的答案。最简单的命令行。我以前见过,但我不记得他们是怎么做到的。
  • 根据我的回答定义环境变量或指定系统变量不会覆盖类路径。
  • 我的意思是,我相信有一种方法可以做到这一点,而无需在命令行上指定 spring.config.location。我知道,因为我已经看到它起作用了;我只是不知道具体情况。我将致力于制作一个 Github 示例项目,如果我能自己解决,请分享。
  • 问题可能是你在哪里看到的。 Afaik intelij idea 默认情况下会这样做。
  • 发现将workingDirectory arg 传递给spring-boot-maven-plugin 解决了我的问题。 Spring 现在自动扫描我设置工作目录的/config 文件夹。
【解决方案3】:

我发现了一个 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

【讨论】:

    猜你喜欢
    • 2018-03-28
    • 2016-04-28
    • 2017-01-04
    • 2016-05-20
    • 2015-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-02
    相关资源
    最近更新 更多