【问题标题】:spring.profiles is not working as expected in spring bootspring.profiles 在 Spring Boot 中没有按预期工作
【发布时间】:2017-10-27 03:31:51
【问题描述】:

启动配置 *.yml 文件。

server.port: 2222
spring:
  application:
    name: x-service
  data:
    mongodb:
       host: db.x
       database: x
#       userName: ${db.userName}
#       password: ${db.password}
  rabbitmq:
#    port: ${queue.port}
    host: queue.x
    username: ${queue.userName}
    password: ${queue.password}
    listener:
      max-concurrency: 1
      prefetch: 1
      acknowledge-mode: auto
      auto-startup: true
    dynamic: true

###########DEV##############
spring.profiles: dev
#queue.virtual.host: xuser 
queue.userName: guest
queue.password: guest
queue.port: 5672

#db.userName: 
#db.password:

falconUrl: http://x.y.com
##########DEFAULT###########
spring.profiles: qa
queue.virtual.host: xuser 
queue.userName: xuser
queue.password: xpassword
queue.port: 3456

db.userName: xuser
db.password: xpassword

falconUrl: http://x.z.com

它给了我 org.yaml.snakeyaml.parser.ParserException: while parsing MappingNode

 in 'reader', line 1, column 1:
    server.port: 2222
    ^
Duplicate key: spring.profiles
 in 'reader', line 47, column 1:

错误。如果我评论其中一个配置文件的属性。它工作正常。 谁能建议这里有什么问题?

【问题讨论】:

  • afaik 只能与 spring: profile: 一起使用,否则它将被解析为单个属性。您必须嵌套它们才能工作..

标签: spring-boot yaml


【解决方案1】:

错误消息实际上非常具体和准确:在 YAML 文件的顶级映射中(以键值对 server.port2222 开头的映射,您有两个相同的键(标量 @987654329 @)。并且 YAML 中不允许有重复的键,因为必须是 unique according to the specification

根本问题是,如果您想根据环境更改配置,则必须遵循documented specification,其中指出:

一个YAML文件实际上是一个由---行分隔的文档序列,每个文档被单独解析成一个扁平化的图。

如果 YAML 文档包含 spring.profiles 键,则配置文件值(以逗号分隔的配置文件列表)被输入 Spring Environment.acceptsProfiles() 并且如果这些配置文件中的任何一个处于活动状态,则该文档将包含在最终合并(否则不合并)

您的 YAML 文件是单个隐式 YAML 文档,因为它缺少出现在显式 YAML 文档开头的指令指示符 ---。 (YAML 指令... 表示文档结束可能不被蛇 yaml 正确支持,至少在示例中没有提到)。

您的代码应如下所示:

server.port: 2222
spring:
  application:
    name: x-service
  data:
    mongodb:
       host: db.x
       database: x
#       userName: ${db.userName}
#       password: ${db.password}
  rabbitmq:
#    port: ${queue.port}
    host: queue.x
    username: ${queue.userName}
    password: ${queue.password}
    listener:
      max-concurrency: 1
      prefetch: 1
      acknowledge-mode: auto
      auto-startup: true
    dynamic: true

###########DEV##############
---
spring.profiles: dev
#queue.virtual.host: xuser 
queue.userName: guest
queue.password: guest
queue.port: 5672

#db.userName: 
#db.password:

falconUrl: http://x.y.com
##########DEFAULT###########
---
spring.profiles: qa
queue.virtual.host: xuser 
queue.userName: xuser
queue.password: xpassword
queue.port: 3456

db.userName: xuser
db.password: xpassword

falconUrl: http://x.z.com

文档中“每个文档都被单独解析为扁平化地图”的声明当然只有在每个文档在顶层都有一个映射时才是正确的。这是 spring-boot 所期望的,但是您可以轻松地在文档的顶层拥有一个标量或序列,并且此类文档肯定不会被蛇 yaml 解析为平面图。

【讨论】:

  • Anthod,说明有误。可以根据环境选择属性stackoverflow.com/questions/34615466/…。我错过了“---”标签
  • 我不知道你在写什么。 '---' 不是标签。在 YAML 中,每个 a 标签都以感叹号 (!) 开头
  • 相同的 YML 文件在如下更改后工作正常 --- ##########DEV############## spring.profiles : dev #queue.virtual.host: xuser queue.userName: guest queue.password: guest falconUrl: x.y.com --- ##########DEFAULT########### spring.profiles:qa queue.virtual.host:xuser queue.userName:xuser queue.password:xpassword falconUrl:x.z.com ---。甚至支持重复的键,并且将根据环境选择值。您也可以在docs.spring.io/spring-boot/docs/current/reference/html/… 中进行验证。
  • 在 YAML 中 --- 是一个指令指示符。它结束新文档的指令并隐式启动新文档。当然,您可以在不同 YAML 文档的顶级映射中使用相同的键,如果这样做,错误就会消失。但这不是您帖子中 YAML 的问题,您确实有一个带有单个文档的 YAML 文件。您不妨将文件设为空,这样它也不会有重复的键。
猜你喜欢
  • 1970-01-01
  • 2016-10-25
  • 1970-01-01
  • 2021-09-03
  • 2014-02-22
  • 1970-01-01
  • 2022-12-08
  • 2021-11-01
  • 2014-01-26
相关资源
最近更新 更多