Spring boot application.properties maven 多模块项目

Posted

技术标签:

【中文标题】Spring boot application.properties maven 多模块项目【英文标题】:Spring boot application.properties maven multi-module projects 【发布时间】:2014-06-02 00:58:47 【问题描述】:

我们在一个多模块项目中使用spring boot。

我们有一个域访问模块,它具有公共域对象类、存储库以及数据源、JPA、Hibernate 等的配置。这些是使用 application.properties 配置的。我们将所有这些配置都放到了公共模块中,以免在更高级别的模块中重复这些公共配置。

在构建域模块时,这一切正常,因此配置在测试单元中正确加载。

但是,当我们尝试在更高层模块中使用域模块时,问题就开始了;它们有自己的 application.properties,这意味着 Spring 加载它们而不是域模块 application.properties,这意味着未配置数据源,因为只加载了更高的模块 application.properties。

我们想要的是 Spring 加载的域模块和更高级别的应用程序属性。但是我们看不到任何简单的方法来做到这一点。

我想这一定是一个常见问题,不知道是否有针对此问题的推荐解决方案?

当我们使用 spring-boot 时,理想情况下,解决方案应该使用注解而不是 applictionContext.xml。

【问题讨论】:

【参考方案1】:

在 spring-boot 中自 2.4 支持 spring.config.import

例如

application.name=myapp
spring.config.import=developer.properties

# import from other module
spring.config.import=classpath:application-common.properties

spring.config.activate.on-profile

spring.config.activate.on-profile=prod
spring.config.import=prod.properties

参考:https://spring.io/blog/2020/08/14/config-file-processing-in-spring-boot-2-4

【讨论】:

【参考方案2】:

您可以做的另一件事(除了 Dave Syer 提到的仅在顶层使用 application.properties 之外)是将域模块的属性文件命名为 domainConfig.properties

这样可以避免名称与application.properties 发生冲突。

domainConfig.properties 将包含域模块能够自行测试所需的所有数据。可以使用多个@PropertySource(一个用于domainConfig.properties,一个用于application.properties)或在Java Config 中配置PropertySourcesPlaceholderConfigurer bean 轻松完成与其余代码的集成(查看this 教程)引用所有需要的属性文件

【讨论】:

这就是我所说的,但如果它让任何人都更清楚,那就太好了。我不建议使用另一个PropertySourcesPlaceholderConfigurer(它只是重复了已经存在的那个),但我想如果你不能在运行时更改spring.config.* 属性,这是一个选择。 好的,我误解了你的回答,我以为你的意思是完全放弃域中的属性文件并使用顶层唯一的属性文件。很抱歉!【参考方案3】:

也许另一种方法是为每个模块定义特定的配置文件并使用 application.properties 文件来指定哪些配置文件处于活动状态 使用spring.profiles.include 属性。

domain-module
- application.properties
- application-domain.properties

app-module
- application.properties
- application-app.properties

进入app-module的application.properties文件

spring.profiles.include=domain,app

【讨论】:

【参考方案4】:

我同意@Dave Syer 的观点。将应用程序拆分为多个模块的想法是,每个模块都是一个独立的单元,在本例中是一个 jar 文件。从理论上讲,您可以将这些 jar 文件中的每一个拆分到它们自己的源存储库中,然后在多个项目中使用它们。假设您想在 Web 和批处理应用程序中重用这些域类,如果所有 APPLICATION 级别的配置都存储在每个单独的模块中,则会严重降低它们的可重用性。

IMO 只有聚合模块应该包含作为应用程序运行所需的所有配置,其他所有内容都只是一个可以根据需要重新混合和重用的依赖项。

【讨论】:

我正在寻找的是在子模块中设置默认属性值的良好约定。然后聚合器模块只需要关心他们自己改变他们需要改变的子模块属性,而不是所有的子模块属性。如果您考虑一下,这就是 Spring Boot 的工作原理;它的 JDBC、JPA、WEB 项目都有常用的默认值,然后你只需要更改你感兴趣的。 那么在这种情况下,为什么不使用 Spring Boot AutoConfiguration?如果您真的在设置属性(数据源 url 等),我认为这不一定与 spring boot 所做的相同 - 他们正在选择适当的依赖项和与环境无关的设置,设置类似数据源的东西是由定义应用程序特定。至少对我来说,每个 jar 应该只包含代码,并且特定于应用程序的配置应该存在于聚合应用程序中。【参考方案5】:

也许您应该只在***聚合器项目中使用application.properties

您始终可以在子项目中使用 @PropertySource 为它们配置一个特定于其用例的名称。

或者您可以为每个项目使用不同的名称,并使用spring.config.location(逗号分隔)将它们粘合到***项目中。

【讨论】:

如果我们在***聚合器项目中确实有属性文件,我们如何为子项目编写测试?我们是否应该在子项目的测试资源中再次拥有这些属性? 我所做的是创建了另一个子模块,其中包含所有测试属性,并在所有其他具有范围测试的模块中导入。这样就无需将属性复制到所有子模块。

以上是关于Spring boot application.properties maven 多模块项目的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Spring Boot REST 应用程序中重用类?

springboot初学---使用redis

Spring Boot 学习例子

Spring Boot 2Spring Boot CLI

为啥 Spring Boot 应用程序 pom 同时需要 spring-boot-starter-parent 和 spring-boot-starter-web?

《02.Spring Boot连载:Spring Boot实战.Spring Boot核心原理剖析》