【问题标题】:Multi-context spring-boot application: how to define standard spring-boot properties for each child context多上下文 spring-boot 应用程序:如何为每个子上下文定义标准 spring-boot 属性
【发布时间】:2019-06-15 22:26:55
【问题描述】:

question 关于添加多个 tomcat 连接器并将它们绑定到每个单独的控制器的能力很好。

安迪威尔金森的好答案的精髓就在这里:

public static void main(String[] args) {
    SpringApplicationBuilder parentBuilder 
            = new SpringApplicationBuilder(ApplicationConfiguration.class);
    parentBuilder.child(ServiceOneConfiguration.class)
            .properties("server.port:8080").run(args);
    parentBuilder.child(ServiceTwoConfiguration.class)
            .properties("server.port:8081").run(args);      
}

我想继续问另一个问题:

有没有办法让每个子应用程序上下文读取一些特定于子应用程序的属性,并支持所有标准 spring-boot 的功能,例如配置文件后缀文件名等。

实现它的一种假设方法:

拥有三个独立的属性文件:

  • application.properties
  • child1.properties
  • child2.properties

并且能够为每个上下文设置一个文件。

但对我来说重要的是,它们必须支持所有 spring-boot 魔法。例如,如果我像传递命令行参数--spring.profiles.active=dev 一样激活新配置文件,那么不仅应该自动加载这三个文件(每个上下文一个),而且还应该自动加载另一组文件(如果它们存在):

  • application-dev.properties
  • child1-dev.properties
  • child2-dev.properties

当然,这些文件应该按照定义的顺序等在标准 spring-boot 支持的路径中搜索。

如果有一些编码的盒子有可能吗?

实现它的另一种假设方式

只有一个application.properties 文件(支持配置文件等),但以某种方式将前缀属性映射到子上下文的无前缀属性。

例子:

child1.server.port=8081
child1.foo=bar
child2.server.port=8082
child2.foo=baz

第一个子上下文应该看到这些属性,就像它们只是:

server.port=8081
foo=bar

第二个子上下文应该看到这些属性,就像它们只是:

server.port=8082
foo=baz

因此,标准 spring-boot 的自动配置将起作用并正确设置 tomcat 的端口等。


我不是在寻找具体的方法(但如果你问我,我倾向于第二种方法),但任何开箱即用的工作或可通过最少的条件实现的方法都足以满足我的需求。

【问题讨论】:

  • 理论上将值设置为spring.config.nameapplication,child1 应该可以解决问题。否则,您可以尝试将其作为参数传递给 run 方法。

标签: java spring spring-boot


【解决方案1】:

您可以使用spring.config.name 实现您的第一个建议:

public static void main(String[] args) {
    SpringApplicationBuilder parentBuilder =
            new SpringApplicationBuilder(ParentApplication.class)
                    .web(WebApplicationType.NONE);
    parentBuilder.run(args);
    parentBuilder.child(ServiceOneConfiguration.class)
            .properties("spring.config.name=child1").run(args);
    parentBuilder.child(ServiceTwoConfiguration.class)
            .properties("spring.config.name=child2").run(args);
}

然后您可以使用child1{-profile}.propertieschild2{-profile}.properties 分别配置服务一和服务二。

例如,server.port=8081 位于 child1.properties 中,server.port=8082 位于 child2.properties 中,当启动在两个子服务中使用自动配置且依赖于spring-boot-starter-web:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.2.RELEASE)

2019-01-22 13:38:09.690  INFO 80968 --- [           main] com.example.parent.ParentApplication     : Starting ParentApplication on …
2019-01-22 13:38:09.692  INFO 80968 --- [           main] com.example.parent.ParentApplication     : No active profile set, falling back to default profiles: default
2019-01-22 13:38:09.842  INFO 80968 --- [           main] com.example.parent.ParentApplication     : Started ParentApplication in 0.371 seconds (JVM running for 0.644)

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.2.RELEASE)

2019-01-22 13:38:10.046  INFO 80968 --- [           main] com.example.parent.ParentApplication     : No active profile set, falling back to default profiles: default
2019-01-22 13:38:10.584  INFO 80968 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8081 (http)
2019-01-22 13:38:10.604  INFO 80968 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2019-01-22 13:38:10.605  INFO 80968 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.14]
2019-01-22 13:38:10.613  INFO 80968 --- [           main] o.a.catalina.core.AprLifecycleListener   : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [/Users/awilkinson/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:.]
2019-01-22 13:38:10.668  INFO 80968 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2019-01-22 13:38:10.668  INFO 80968 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 612 ms
2019-01-22 13:38:10.829  INFO 80968 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2019-01-22 13:38:10.981  INFO 80968 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8081 (http) with context path ''
2019-01-22 13:38:10.981  INFO 80968 --- [           main] com.example.parent.ParentApplication     : Started ParentApplication in 0.955 seconds (JVM running for 1.784)

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.2.RELEASE)

2019-01-22 13:38:11.003  INFO 80968 --- [           main] com.example.parent.ParentApplication     : No active profile set, falling back to default profiles: default
2019-01-22 13:38:11.093  INFO 80968 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8082 (http)
2019-01-22 13:38:11.095  INFO 80968 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2019-01-22 13:38:11.096  INFO 80968 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.14]
2019-01-22 13:38:11.100  INFO 80968 --- [           main] o.a.c.c.C.[Tomcat-1].[localhost].[/]     : Initializing Spring embedded WebApplicationContext
2019-01-22 13:38:11.101  INFO 80968 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 97 ms
2019-01-22 13:38:11.135  INFO 80968 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2019-01-22 13:38:11.164  INFO 80968 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8082 (http) with context path ''
2019-01-22 13:38:11.165  INFO 80968 --- [           main] com.example.parent.ParentApplication     : Started ParentApplication in 0.183 seconds (JVM running for 1.967)

【讨论】:

  • 谢谢,安迪,它有效。只是澄清一下:在运行子上下文以使其工作之前,我必须执行parentBuilder.run(args);(考虑将其添加到您的答案中)。另附注:开发工具的ConditionEvaluationDeltaLoggingListener 出于某种原因在第一个子上下文开始时和第二个子上下文开始之前触发并打印完整的“条件评估增量”。也许这只是开发工具或其他东西中的一个错误。
  • 谢谢。我已经编辑添加parentBuilder.run(args);。条件评估增量行为听起来像一个错误。如果您希望我们查看,请为它打开一个问题 (github.com/spring-projects/spring-boot/issues)。
猜你喜欢
  • 2019-08-13
  • 2015-09-14
  • 2020-06-08
  • 2015-11-12
  • 2021-10-11
  • 1970-01-01
  • 2018-01-20
  • 2019-06-16
  • 1970-01-01
相关资源
最近更新 更多