Configuration Reference Guide
本指南的内容已进行修订并拆分为其他多个主题。请查看 Additional Information 小节。
在本参考指南中,我们将描述 Quarkus 配置的各个方面。Quarkus 应用程序和 Quarkus 本身(核心和扩展)都是通过相同的机制进行配置的,该机制利用 SmallRye Config API(实现 MicroProfile Config 规范)。
如果您正在寻找有关如何使 Quarkus 扩展可配置的信息,请参阅 Writing Your Own Extension 指南。 |
- Config Sources
- Inject
- Programmatically access
- Profiles
- Property Expressions
- Secret Keys Expressions
- Accessing a generating UUID
- Clearing properties
- Indexed Properties
- Configuring Quarkus
- Change build time properties after your application has been published
- Tracking effective build time configuration used at build time
- Config property values injected during static initialization phase
- Additional Information
- Configuration Reference
Config Sources
默认情况下,Quarkus 从多个来源读取配置属性(按降序排列):
-
(400) system-properties
-
(300) environment-variables
-
(295) 当前工作目录中的 .env 文件
-
(260)
$PWD/config/application.properties
中的 Quarkus Application configuration file -
(250) 类路径中的
application.properties
Quarkus Application configuration file -
(100) 类路径中的
META-INF/microprofile-config.properties
MicroProfile Config configuration file
最终配置是所有这些来源定义的属性的聚合。配置属性查找从可用的最高序号配置源开始,然后一直向下到其他来源,直到找到匹配项。这意味着任何配置属性都可以仅通过在较高序号配置源中设置不同的值来覆盖该值。例如,使用环境属性配置的属性将覆盖使用 application.properties
文件提供的属性。
System properties
系统属性可以在启动期间通过 -D
标志传递给应用程序。以下示例将值 youshallnotpass
分配给属性 quarkus.datasource.password
。
-
对于 Quarkus 开发模式:
./mvnw quarkus:dev -Dquarkus.datasource.password=youshallnotpass
-
对于 runner jar:
java -Dquarkus.datasource.password=youshallnotpass -jar target/quarkus-app/quarkus-run.jar
-
对于本机可执行文件:
./target/myapp-runner -Dquarkus.datasource.password=youshallnotpass
Environment variables
-
对于 runner jar:
export QUARKUS_DATASOURCE_PASSWORD=youshallnotpass ; java -jar target/quarkus-app/quarkus-run.jar
-
对于本机可执行文件:
export QUARKUS_DATASOURCE_PASSWORD=youshallnotpass ; ./target/myapp-runner
环境变量名称遵循 MicroProfile Config 指定的转换规则。Config 为给定的属性名称(例如 foo.BAR.baz
)搜索三个环境变量:
-
foo.BAR.baz
- Exact match -
foo_BAR_baz
- 用替换每一个既不是字母数字字符也不是
的字符
-
FOO_BAR_BAZ
- 用替换每一个既不是字母数字字符也不是
的字符;然后将名称转换为大写字母
SmallRye Config 指定 additional conversion rules。
-
带双引号的属性
foo."bar".baz
,将每个既不是字母数字的字符也的字符都替换为
:
FOOBARBAZ
-
带破折号的属性
foo.bar-baz
,将每个既不是字母数字的字符也的字符都替换为
:
FOO_BAR_BAZ
-
索引属性
foo.bar[0]
或foo.bar[0].baz
,将每个既不是字母数字的字符也的字符都替换为
:
FOO_BAR_0_
或FOO_BAR_0__BAZ
在某些情况下,查找精确的属性名称是不可能的。这是对于包含用户定义路径段的配置名称来说的情况。
应用环境变量名称的转换规则,quarkus.datasource."datasource-name".jdbc.url
变成了 QUARKUS_DATASOURCEDATASOURCE_NAMEJDBC_URL
。如果这两个属性都可在 Config 系统中使用,该配置将按预期返回结果。
如果只有 QUARKUS_DATASOURCEDATASOURCE_NAMEJDBC_URL
(存在),Config 系统需要将该配置名称重新转换为其最可能的带点的格式。对固定的配置段来说这样很好,但对包含动态段的名称来说不行。在此情况下,Quarkus 无法确定 DATASOURCE_NAME
应当转换为 datasource.name
还是 datasource-name
(或任何其他特殊字符分隔符)。
出于此原因,此类属性总要求其点分版本名称在另一个源中(值可以留空)以消除环境变量名称歧义。它将提供额外的信息来执行双向转换,并将属性名称匹配在一起。
# value can be left empty
quarkus.datasource."datasource-name".jdbc.url=
EXPORT QUARKUS_DATASOURCE__DATASOURCE_NAME__JDBC_URL=jdbc:postgresql://localhost:5432/database
.env
file in the current working directory
QUARKUS_DATASOURCE_PASSWORD=youshallnotpass 1
1 | 该名称 QUARKUS_DATASOURCE_PASSWORD 遵循与对 Environment variables 使用相同的转换规则。 |
对于 dev
模式,该文件可以放在项目的根中,但建议将其检查到 not 版本控制中,因为它通常包含密码、访问令牌、API 密钥或其他机密。
.env
文件中的环境变量无法通过 System.getenv(String)
API 使用。
Quarkus Application configuration file
Quarkus 应用程序配置文件从类路径资源中加载,例如 src/main/resources/application.properties
、src/test/resources/application.properties
或从一个 jar
依赖项中(包含一个 application.properties
项)。发现的每个 application.properties
都被视为一个单独的 ConfigSource
,并遵循与任何其他源一样的规则(按属性覆盖)。另外,配置文件也 $PWD/config/application.properties
驻留。从配置文件夹中开始加载,然后再是类路径顺序(application.properties
文件在应用程序源中在类加载器加载顺序中具有优先级)。
application.properties
greeting.message=hello 1
quarkus.http.port=9090 2
1 | 这是一个用户定义的配置属性。 |
2 | 这是一个由 quarkus-vertx-http 扩展使用的配置属性。 |
|
MicroProfile Config configuration file
在 src/main/resources/META-INF/microprofile-config.properties
中的 MicroProfile Config 配置文件。
microprofile-config.properties
greeting.message=hello 1
quarkus.http.port=9090 2
1 | 这是一个用户定义的配置属性。 |
2 | 这是一个由 quarkus-vertx-http 扩展使用的配置属性。 |
它以与 Quarkus 应用程序配置文件 |
Locations
除了默认配置位置外,Quarkus 还提供一种扫描配置文件的其他位置的方法。
quarkus.config.locations`配置属性接受多个由逗号分隔的位置,
,且每个都必须表示有效的 `URI
。受支持的 `URI`架构包括:
-
file or directory (
file:
) -
classpath resource
-
jar resource (
jar:
) -
http resource (
http:
)
所有已加载源都使用找到 quarkus.config.locations`配置属性的源的相同序数。例如,如果 `quarkus.config.locations`被设定为系统属性,那么所有已加载的源都可以将其序数设定为 `400
(系统属性使用 `400`作为其序数)。可以通过设置 `config_ordinal`属性和序数值来直接覆盖每个配置源的序数。`config_ordinal`属性只影响其中被设置的源的序数。源首先按其序数排序,然后按位置顺序排序,最后按加载顺序排序。
Inject
Quarkus 使用 MicroProfile Config 注释,向应用程序中注入配置属性。
@ConfigProperty(name = "greeting.message") 1
String message;
1 | 你可以使用 @Inject @ConfigProperty 或只是 @ConfigProperty 。对于使用 @ConfigProperty 注释的成员,不必使用 @Inject 注释。 |
如果应用程序试图注入一个未设置的配置属性,将抛出错误。 |
@ConfigProperty(name = "greeting.message") 1
String message;
@ConfigProperty(name = "greeting.suffix", defaultValue="!") 2
String suffix;
@ConfigProperty(name = "greeting.name")
Optional<String> name; 3
1 | 如果你未为该属性提供值,应用程序启动将使用 jakarta.enterprise.inject.spi.DeploymentException: No config value of type [class java.lang.String] exists for: greeting.message 失败。 |
2 | 如果配置未为 greeting.suffix 提供值,将注入默认值。 |
3 | 此属性为可选项——如果配置未为 greeting.name 提供值,将注入一个空 Optional 。 |
使用 Config Mappings对相似的配置属性进行分组。 |
Default Values
如果某个属性与默认值(通过 defaultValue`属性)相关联,并且没有为该属性提供配置值,那么不会抛出 `jakarta.enterprise.inject.spi.DeploymentException
,而是将使用默认值。defaultValue`值表示为 `String
,并使用与处理配置值相同的转换机制。内置转换器已经存在很多用于基元、装箱基元和其他类的转换器;例如:
-
基元:
boolean
、byte
、`short`等。 -
装箱基元:
java.lang.Boolean
、java.lang.Byte
、`java.lang.Short`等。 -
可选容器:
java.util.Optional
、java.util.OptionalInt
、java.util.OptionalLong`和 `java.util.OptionalDouble
-
Java
enum
types -
JSR 310
java.time.Duration
-
JDK 网络:
java.net.SocketAddress
、`java.net.InetAddress`等。
正如您所料,这些转换器都是 `org.eclipse.microprofile.config.spi.Converter`实现。因此,这些转换器符合 Microprofile 或自定义实现提供程序表达规则,如下所示:
-
布尔值在“true”、“1”、“YES”、“Y”、“ON”情况下将为
true
。否则,该值将被解释为 false -
对于 float 和 double 值,小数位必须用点 `.`分隔。
请注意,当 `Optional*`类型和 `defaultValue`属性的组合使用时,已定义的 `defaultValue`仍将被使用,并且如果没有为属性指定值,则 `Optional*`将存在并填入转换后的默认值。但是,当该属性明确为空时,则不使用默认值并且 `Optional`将为空。考虑以下示例:
# missing value, optional property
greeting.name=
在这种情况下,由于在上面已将 greeting.name`配置为 `Optional*
,因此相应的属性值将为空的 Optional
,并且执行将正常继续。即使存在已配置的默认值,情况也是如此:如果在配置中明确清除了该属性,则使用该默认值 not。
另一方面,此示例:
# missing value, non-optional
greeting.suffix=
将在启动时导致 `java.util.NoSuchElementException: SRCFG02004: Required property greeting.message not found`并且不会分配默认值。
以下是 Quarkus 提供的转换器的示例:
@ConfigProperty(name = "server.address", defaultValue = "192.168.1.1")
InetAddress serverAddress;
Programmatically access
org.eclipse.microprofile.config.ConfigProvider.getConfig()
API 允许以编程方式访问配置 API。此 API 主要在 CDI 注入不可用的情况下有用。
String databaseName = ConfigProvider.getConfig().getValue("database.name", String.class);
Optional<String> maybeDatabaseName = ConfigProvider.getConfig().getOptionalValue("database.name", String.class);
不要使用 `System.getProperty(String)`或 `System.getEnv(String)`来检索配置值。这些 API 不了解配置,并且不支持本指南中描述的功能。
Profiles
我们经常需要根据目标_environment_来不同地配置应用程序。例如,本地开发环境可能不同于生产环境。
配置文件允许在同一文件中或单独的文件中进行多个配置,并通过配置文件名在它们之间进行选择。
Profile in the property name
为了能够设置具有相同名称的属性,每个属性需要使用百分比符号 %
加上配置文件名和一个点 .
作为前缀,语法如下 %{profile-name}.config.name
:
quarkus.http.port=9090
%dev.quarkus.http.port=8181
Quarkus 的 HTTP 端口为 9090。如果 dev
的配置文件处于启用状态,则为 8181。
.env
文件中的配置文件遵循语法 _{PROFILE}_CONFIG_KEY=value
:
QUARKUS_HTTP_PORT=9090
_DEV_QUARKUS_HTTP_PORT=8181
如果某个配置文件未为特定属性定义值,则会使用 default (无配置文件)的值:
bar=”hello”
baz=”bonjour”
%dev.bar=”hallo”
当 dev
配置文件启用时,属性 bar
的值为 hallo
,但属性 baz
的值为 bonjour
。如果 prod
配置文件启用,则 bar
的值为 hello
(因为没有针对 prod
配置文件的具体值),而 baz
的值为 bonjour
。
Default Profiles
默认情况下,Quarkus 提供三个配置文件,它们会在特定条件下自动激活:
-
dev——在开发模式中激活(即
quarkus:dev
) -
test——在运行测试时激活
-
prod——不在开发或测试模式中运行时的默认配置文件
Custom Profiles
还可以创建其他配置文件,并使用 quarkus.profile
配置属性来激活它们。唯一的要求是使用新配置文件名称设置单个配置属性:
quarkus.http.port=9090
%staging.quarkus.http.port=9999
将 quarkus.profile
设置为 staging
将激活 staging
配置文件。
|
Profile aware files
在这种情况下,特定配置文件的属性可能驻留在名为 application-{profile}.properties
的文件中。先前的示例可以表示为:
quarkus.http.port=9090
%staging.quarkus.http.test-port=9091
quarkus.http.port=9190
quarkus.http.test-port=9191
在这种样式中,配置文件感知文件中的配置名称不需要以配置文件名称为前缀。 配置文件感知文件中的属性优先于主文件中定义的配置文件感知属性。 |
不要使用配置文件感知文件来设置 quarkus.profile
或 quarkus.test.profile
。这不起作用,因为配置文件在加载配置文件感知文件之前是必需的。
仅当未生成配置文件的“@ [1]” 也在同一位置可用,并且文件扩展名在这些文件之间匹配时,才会加载配置文件感知文件。这样做是为了保持一致的加载顺序,并将所有一起配对资源。
Parent Profile
父配置文件为当前配置文件添加一个级别的层次结构。配置 “@ [5]” 接受一个个人配置文件名称。
在父配置文件处于活动状态时,如果在当前活动配置文件中找不到属性,则配置查找会降级为父配置文件。考虑:
quarkus.profile=dev
quarkus.config.profile.parent=common
%common.quarkus.http.port=9090
%dev.quarkus.http.ssl-port=9443
quarkus.http.port=8080
quarkus.http.ssl-port=8443
然后
-
活动配置文件为“@ [6]”
-
父配置文件为“@ [7]”
-
quarkus.http.port
is 9090 -
quarkus.http.ssl-port
is 9443
不要使用配置文件感知文件来设置 “@ [8]”。这将不起作用,因为提前需要配置文件才能加载配置文件感知文件。
Multiple Profiles
多个配置文件可以同时处于活动状态。配置 “@ [9]” 接受以逗号分隔的个人配置文件名称列表: “@ [10]”。“@ [11]” 和 “@ [12]” 都是单独的个人配置文件。
当多个配置文件处于活动状态时,配置文件配置的规则是相同的。如果两个配置文件定义相同的配置,则最后列出的配置文件具有优先权。考虑:
quarkus.profile=common,dev
my.prop=1234
%common.my.prop=1234
%dev.my.prop=5678
%common.commom.prop=common
%dev.dev.prop=dev
%test.test.prop=test
然后
-
common.prop
value iscommon
-
dev.prop
value isdev
-
my.prop
value is5678
-
“@ [13]” 没有 “@ [14]”
还可以使用以逗号分隔的个人配置文件名称列表定义多个配置文件属性。如果相同的属性名称存在于多个配置文件属性中,则具有最特定配置文件的属性名称获胜:
quarkus.profile=dev
%prod,dev.my.prop=1234
%dev.my.prop=5678
%prod,dev.another.prop=1234
然后
-
my.prop
value is 5678. -
another.prop
value is 1234.
多个配置文件的优先级按相反的顺序处理。“@ [15]”,Quarkus 首先检查 “@ [16]” 个人配置文件,然后检查 “@ [17]” 个人配置文件。
Property Expressions
Quarkus 在配置值上提供属性表达式扩展。表达式字符串是纯字符串和表达式片段的混合,由序列 “@ [20]” 包装。
在读取属性时解析这些表达式。因此,如果配置属性是构建时间,则属性表达式将在构建时解析。如果可以在运行时覆盖配置属性,则将在运行时解析它。
考虑:
remote.host=quarkus.io
callable.url=https://${remote.host}/
“@ [21]” 属性的解析值是 “@ [22]”。
另一个示例是按配置文件定义不同的数据库服务器:
%dev.quarkus.datasource.jdbc.url=jdbc:mysql://localhost:3306/mydatabase?useSSL=false
quarkus.datasource.jdbc.url=jdbc:mysql://remotehost:3306/mydatabase?useSSL=false
简化后为:
%dev.application.server=localhost
application.server=remotehost
quarkus.datasource.jdbc.url=jdbc:mysql://${application.server}:3306/mydatabase?useSSL=false
此外,“表达式扩展”引擎支持以下部分:
-
${expression:value}
——如果扩展未找到值,在:
后提供默认值。 -
${my.prop${compose}}
——组合表达式。内部表达式优先解析。 -
${my.prop}${my.prop}
- Multiple expressions.
如果无法扩展表达式且未提供默认值,则会抛出 NoSuchElementException
。
在所有配置源中执行表达式查找。表达式值和扩展值可能位于不同的配置源中。 |
Secret Keys Expressions
机密配置可表示为 ${handler::value}
,其中 handler
是用于对 value
进行解码或解密的 io.smallrye.config.SecretKeysHandler
的名称。请考虑:
my.secret=${aes-gcm-nopadding::DJNrZ6LfpupFv6QbXyXhvzD8eVDnDa_kTliQBpuzTobDZxlg}
# the encryption key required to decode the secret. It can be set in any source.
smallrye.config.secret-handler.aes-gcm-nopadding.encryption-key=somearbitrarycrazystringthatdoesnotmatter
查找 my.secret
将使用 SecretKeysHandler
名称 aes-gcm-nopadding
对值 DJNrZ6LfpupFv6QbXyXhvzD8eVDnDa_kTliQBpuzTobDZxlg
进行解码。
如需了解更多信息,请查看 SmallRye 配置 Secret Keys 文档。
SmallRye 配置可能会提供 Quarkus 完全不支持的处理程序。当前,仅支持 smallrye-config-crypto
。
Accessing a generating UUID
Quarkus 的默认配置源提供随机的 UUID 值。它在启动时生成 UUID。因此,值在启动(包括开发模式中的重新加载)之间发生变化。
可以使用 quarkus.uuid
属性访问生成的值。使用 expressions 访问它: ${quarkus.uuid}
。例如,它可用于使用唯一消费者组配置 Kafka 客户端:
mp.messaging.incoming.prices.group.id=${quarkus.uuid}
Clearing properties
可选的运行时属性,且在构建时或具有默认值时已设置了值,可以通过向属性分配一个空字符串来明确清除。请注意,这将影响运行时属性,并且与不需要其值属性一起使用时不适用。
remote.host=quarkus.io
使用 -Dremote.host=
查找 remote.host
时将抛出异常,因为系统属性已清除该值。
Indexed Properties
包含未转义逗号的配置值可以转换为 Collection
。这适用于简单的情况,但对于更高级的情况来说,它会变得繁琐且受限。
索引属性提供了一种在配置属性名称中使用索引的方法,以映射 Collection
类型中的特定元素。由于索引元素是属性名称的一部分,不包含在值中,因此也可将其用于映射复杂的对象类型,如 Collection
元素。请考虑:
my.collection=dog,cat,turtle
my.indexed.collection[0]=dog
my.indexed.collection[1]=cat
my.indexed.collection[2]=turtle
索引属性语法使用属性名称和带有索引的中括号 [ ]
。
调用 Config#getValues("my.collection", String.class)
时,将自动创建和转换 List<String>
,其中包含 dog
、cat
和 turtle
等值。调用 Config#getValues("my.indexed.collection", String.class)
会返回完全相同的结果。如果同一属性名称同时存在于常规形式和索引形式中,则常规值具有优先级。
在添加到目标 Collection`之前,会根据索引对索引属性进行排序。索引中包含的任何间隙都不会解析为目标 `Collection
,这意味着 Collection
结果将存储所有值,没有任何间隙。
Configuring Quarkus
Quarkus 本身使用与应用程序相同的机制进行配置。Quarkus 保留 quarkus.
命名空间用于自身配置。例如,要配置 HTTP 服务器端口,您可以在 application.properties
中设置 quarkus.http.port
。所有 Quarkus 配置属性都是 documented and searchable。
如上所述,以 quarkus.
为前缀的属性实际上是保留用于配置 Quarkus 本身及其扩展的。因此,quarkus.
前缀应该 never 用于应用程序特定属性。
Build Time configuration
某些 Quarkus 配置只在构建时生效,这意味着在运行时无法更改它们。这些配置在运行时仍然可用,但只读且不会影响 Quarkus 行为。要更改任何这些配置,需要重新构建应用程序本身以反映这些属性的更改。
构建时固定的属性会在 list of all configuration options 中用锁图标 () 标记。 |
但是,一些扩展确实定义了属性 overridable at runtime。一个简单的例子是数据库 URL、用户名和密码,这些通常只在您的目标环境中知道,因此可以在运行时设置它们并影响应用程序的行为。
Change build time properties after your application has been published
如果您在应用程序构建后需要更改构建时间配置,则查看如何使用 re-augmentation 为不同的构建时间配置重建增强输出。
Tracking effective build time configuration used at build time
考虑到配置源通常提供的选项多于实际在构建期间使用的选项,了解在 Quarkus 构建过程中实际使用了哪些配置选项可能非常有用。
Dumping build time configuration options read during the build
将 quarkus.config-tracking.enabled
设置为 `true`将启用一个配置拦截器,该拦截器将记录在构建过程中读取的每个配置选项和它们的值。生成的报告将默认存储在 `${project.basedir}/.quarkus/quarkus-prod-config-dump`中。可以通过以下选项配置目标文件:
-
quarkus.config-tracking.directory
——应存储配置转储的目录,默认值为${project.basedir}/.quarkus
-
quarkus.config-tracking.file-prefix
——文件名前缀,默认值为quarkus
-
quarkus.config-tracking.file-suffix
——文件名后缀,默认值为-config-dump
-
quarkus.config-tracking.file
——指向应存储配置转储的文件的路径。此选项取代了file-prefix
和file-suffix
选项。除非该值是相对路径,否则也取代了quarkus.config-tracking.directory
的值。
quarkus-prod-config-dump
文件名中的 prod
部分指的是 Quarkus 构建模式,表示已为生产构建进行了转储。
选择 ${project.basedir}/.quarkus
目录作为默认位置的原因是让它很容易跟踪构建之间的构建时间配置变更,并将其用作指示构建输出缓存工具(例如 Apache Maven Build Cache 和 Develocity Build Cache)是否必须重新构建应用程序二进制文件的指标。
Filtering configuration options
可以通过使用逗号分隔的要过滤掉的配置选项名称来配置 quarkus.config-tracking.exclude
来指示配置跟踪器从报告中排除某些选项。
Tracking build time configuration changes between builds
虽然 quarkus.config-tracking.enabled
启用了有效的构建时配置报告生成,但还有办法在启动项目的下一次构建之前检查存储在该报告中的值是否发生更改。
Maven 项目可以将以下目标添加到其 quarkus-maven-plugin
配置中:
<plugin>
<groupId>${quarkus.platform.group-id}</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<version>${quarkus.platform.version}</version>
<extensions>true</extensions>
<executions>
<execution>
<id>track-prod-config-changes</id>
<phase>process-resources</phase>
<goals>
<goal>track-config-changes</goal>
</goals>
</execution>
<!-- other executions would follow below -->
track-config-changes
目标查找 ${project.basedir}/.quarkus/quarkus-prod-config-dump
(文件名和目录是可配置的),如果文件已存在,则检查 config 转储中存储的值是否已更改。它将记录更改的选项,并将 ${project.basedir}/.quarkus/quarkus-prod-config-dump
中存在的每个选项的当前值保存在 ${project.basedir}/target/quarkus-prod-config.check
中(目标文件名和位置可以配置)。如果自上次构建以来构建时配置没有更改,则 ${project.basedir}/.quarkus/quarkus-prod-config-dump
和 ${project.basedir}/.quarkus/quarkus-prod-config-dump
将相同。
Dump Quarkus application dependencies
除了转储配置值之外,track-config-changes
目标还会转储所有 Quarkus 应用程序依赖项,包括 Quarkus 构建时依赖项。例如,该文件可用于检查自上次运行以来 Quarkus 构建类路径是否已更改,以及 Develocity 计算类路径校验和的能力。默认情况下,依赖项列表将存储在 target/quarkus-prod-dependencies.txt
文件下。可以使用插件参数配置不同的位置。
Dump current build configuration when the recorded configuration isn’t found
默认情况下,track-config-changes
会查找在之前的构建期间记录的配置,如果找不到,它不会执行任何操作。启用 dumpCurrentWhenRecordedUnavailable
参数将使其转储当前构建配置选项,同时考虑 quarkus.config-tracking.*
配置。
与 quarkus:build
目标期间记录的构建配置选项不同,quarkus:track-config-changes
在启用 dumpCurrentWhenRecordedUnavailable
的情况下保存的配置选项将包括 org.eclipse.microprofile.config.Config
实例公开的所有构建配置选项。这意味着此报告可能包含不会被 Quarkus 应用程序构建过程使用的构建配置选项,但还可能缺少一些构建配置选项,因为 MicroProfile Config 规范允许配置源不向用户公开它们提供的全部属性名称。
Config property values injected during static initialization phase
Quarkus 在 static initialization phase 期间收集注入在 CDI Bean 中的配置属性值。然后将收集到的值与其运行时初始化对应的值进行比较,如果检测到不匹配,则应用程序启动失败。怎么会这样?例如,我们有一个 CDI Bean org.acme.MyBean
。MyBean
注入了一个名称为 foo
的 @ConfigProperty
,并在原生构建期间进行初始化。在原生构建期间,配置属性不存在,因此使用默认值 bar
。但是,稍后,当应用程序启动时,该属性使用系统属性定义:-Dfoo=baz
。这将导致状态不一致和行为意外。因此,Quarkus 在这种情况下默认会失败。
package org.acme;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.event.Observes;
import jakarta.enterprise.context.Initialized;
import org.eclipse.microprofile.config.inject.ConfigProperty;
@ApplicationScoped
public class MyBean {
@ConfigProperty(name = "foo", defaultValue = "bar") 1
String foo;
void onInit(@Observes @Initialized(ApplicationScoped.class) Object event) { 2
// this observer method is notified during STATIC_INIT...
}
}
1 | 在创建 bean 时会注入 config 属性,并且会修复此值。 |
2 | 在此特定情况下,观察者 @Initialized(ApplicationScoped.class) 导致了该 bean 初始化。但还有其他可能的情况。例如,有些扩展程序会在静态初始化阶段初始化组件。 |
你可以在注入的字段/参数上使用 @io.quarkus.runtime.annotations.StaticInitSafe
注释,标记注入的配置对象可在静态初始化阶段安全初始化。
package org.acme;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.event.Observes;
import jakarta.enterprise.context.Initialized;
import org.eclipse.microprofile.config.inject.ConfigProperty;
import io.quarkus.runtime.annotations.StaticInitSafe;
@ApplicationScoped
public class MyBeanNoFailure {
@StaticInitSafe 1
@ConfigProperty(name = "foo", defaultValue = "bar")
String foo;
void onInit(@Observes @Initialized(ApplicationScoped.class) Object event) {
// this observer method is notified during STATIC_INIT...
}
}
1 | 指示 Quarkus 在检测到不匹配情况时不要失败。 |