Accessing application properties with Spring Boot properties API
如果你希望使用 Spring Boot @ConfigurationProperties
注解类来访问应用程序属性,而不是 @ConfigMapping
或 MicroProfile @ConfigProperty
方法,你可以使用此扩展。
Spring Boot @ConfigurationProperties
有些局限。例如,不支持注入 Map
。请考虑使用 Mapping configuration to objects。
Prerequisites
Unresolved directive in spring-boot-properties.adoc - include::{includes}/prerequisites.adoc[]
Solution
我们建议您遵循接下来的部分中的说明,按部就班地创建应用程序。然而,您可以直接跳到完成的示例。
克隆 Git 存储库: git clone {quickstarts-clone-url}
,或下载 {quickstarts-archive-url}[存档]。
该解法位于 spring-boot-properties-quickstart
… directory。
Creating the Maven project
首先,我们需要一个新项目。使用以下命令创建一个新项目:
Unresolved directive in spring-boot-properties.adoc - include::{includes}/devtools/create-app.adoc[]
此命令会生成一个项目并导入 spring-boot-properties
扩展。
如果你已经配置好了 Quarkus 项目,则可以按如下方式在项目基本目录中运行以下命令,将 spring-boot-properties
扩展添加到项目:
Unresolved directive in spring-boot-properties.adoc - include::{includes}/devtools/extension-add.adoc[]
这会将以下内容添加到构建文件中:
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-spring-boot-properties</artifactId>
</dependency>
implementation("io.quarkus:quarkus-spring-boot-properties")
GreetingController
首先,以类似如下所示方式在 src/main/java/org/acme/spring/boot/properties/GreetingResource.java
文件中创建一个 GreetingResource
Jakarta REST 资源:
package org.acme.spring.boot.properties;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
@Path("/hello")
public class GreetingResource {
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "hello";
}
}
Injecting properties
创建一个带有 message 字段的新类 src/main/java/org/acme/spring/boot/properties/GreetingProperties.java
:
package org.acme.spring.boot.properties;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties("greeting")
public class GreetingProperties {
public String text;
}
此处的 text
字段是公共字段,但也可以是带 getter 和 setter 方法的私有字段,也可以是接口中的公共 getter。因为 text
没有默认值,因此被视为必需字段,而且除非在配置文件中定义(默认情况下为 application.properties
),否则你的应用程序将启动失败。在你的 src/main/resources/application.properties
文件中定义此属性:
# Your configuration properties
greeting.text=hello
现在修改 GreetingResource
,以开始使用 GreetingProperties
:
package org.acme.spring.boot.properties;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
@Path("/greeting")
public class GreetingResource {
@Inject
GreetingProperties properties;
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return properties.text;
}
}
运行测试,验证应用程序仍能正确运行。
Package and run the application
按如下方式在开发模式下运行应用程序:
Unresolved directive in spring-boot-properties.adoc - include::{includes}/devtools/dev.adoc[]
用浏览器打开 [role="bare"][role="bare"]http://localhost:8080/greeting.
修改配置文件会立即反映出来。
和往常一样,可以使用以下命令打包应用程序:
Unresolved directive in spring-boot-properties.adoc - include::{includes}/devtools/build.adoc[]
并使用 `java -jar target/quarkus-app/quarkus-run.jar`执行。
你还可以按如下方式生成本机可执行文件:
Unresolved directive in spring-boot-properties.adoc - include::{includes}/devtools/build-native.adoc[]
Default values
现在我们添加一个我们设置默认值的问候语后缀。
具有默认值的属性可以像任何其他属性一样在配置文件中配置。但是,如果属性未在配置文件中定义,则将使用默认值。
继续并将新字段添加到 @ [1]
类:
package org.acme.spring.boot.properties;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties("greeting")
public class GreetingProperties {
public String text;
public String suffix = "!";
}
并更新 @ [2]
及其测试 @ [3]
:
package org.acme.spring.boot.properties;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
@Path("/greeting")
public class GreetingResource {
@Inject
GreetingProperties properties;
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return properties.text + properties.suffix;
}
}
package org.acme.spring.boot.properties;
import io.quarkus.test.junit.QuarkusTest;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.is;
@QuarkusTest
public class GreetingResourceTest {
@Test
public void testHelloEndpoint() {
given()
.when().get("/greeting")
.then()
.statusCode(200)
.body(is("hello!"));
}
}
运行测试以验证更改。
Optional values
具有可选值的属性是标准和具有默认值的属性之间的中间值。虽然配置文件中缺少的属性不会导致你的应用程序失败,但它仍然没有设置值。我们使用 @ [4]
类型来定义此类属性。
向 @ [6]
添加一个可选的 @ [5]
属性:
package org.acme.spring.boot.properties;
import java.util.Optional;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties("greeting")
public class GreetingProperties {
public String text;
public String suffix = "!";
public Optional<String> name;
}
并更新 @ [2]
及其测试 @ [3]
:
package org.acme.spring.boot.properties;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
@Path("/greeting")
public class GreetingResource {
@Inject
GreetingProperties properties;
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return properties.text + ", " + properties.name.orElse("You") + properties.suffix;
}
}
package org.acme.spring.boot.properties;
import io.quarkus.test.junit.QuarkusTest;
import org.junit.jupiter.api.Test;
import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.is;
@QuarkusTest
public class GreetingResourceTest {
@Test
public void testHelloEndpoint() {
given()
.when().get("/greeting")
.then()
.statusCode(200)
.body(is("hello, You!"));
}
}
运行测试以验证更改。
Grouping properties
现在我们的 @ [7]
类中有三个属性。虽然 @ [8]
可以被认为更多是一个运行时属性(并且将来可能可以作为 HTTP 查询参数传递),但 @ [9]
和 @ [10]
用于定义一个消息模板。让我们将这两个属性分组到一个单独的内部类:
package org.acme.spring.boot.properties;
import java.util.Optional;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties("greeting")
public class GreetingProperties {
public Message message;
public Optional<String> name;
public static class Message {
public String text;
public String suffix = "!";
}
}
这里 @ [11]
属性类被定义为一个内部类,但它也可以是顶级类。
具有这样的属性组将为你的配置带来更多的结构。当属性数增长时,这一点特别有用。
由于添加了类,我们的属性名称发生了变化。让我们更新属性文件和 @ [12]
类。
# Your configuration properties
greeting.message.text=hello
package org.acme.spring.boot.properties;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
@Path("/greeting")
public class GreetingResource {
@Inject
GreetingProperties properties;
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return properties.message.text + ", " + properties.name.orElse("You") + properties.message.suffix;
}
}