使用 Spring Boot 属性 API 访问应用程序属性
如果您更喜欢使用 Spring Boot @ConfigurationProperties
注解的类来访问应用程序属性,而不是 @ConfigMapping
或 MicroProfile @ConfigProperty
方法,您可以使用此扩展来实现。
Spring Boot @ConfigurationProperties 有一些限制。例如,不支持 Map 注入。请考虑使用 将配置映射到对象。 |
先决条件
要完成本指南,您需要
-
大约 15 分钟
-
一个 IDE
-
已安装 JDK 17+ 并正确配置了
JAVA_HOME
-
Apache Maven 3.9.9
-
如果您想使用它,可以选择 Quarkus CLI
-
如果您想构建本机可执行文件(或者如果您使用本机容器构建,则为 Docker),可以选择安装 Mandrel 或 GraalVM 并进行适当的配置
解决方案
我们建议您按照以下章节中的说明,逐步创建应用程序。但是,您可以直接转到完整的示例。
克隆 Git 仓库:git clone https://github.com/quarkusio/quarkus-quickstarts.git
,或下载 压缩包。
解决方案位于 spring-boot-properties-quickstart
目录中。
创建 Maven 项目
首先,我们需要一个新项目。使用以下命令创建一个新项目
对于 Windows 用户
-
如果使用 cmd,(不要使用反斜杠
\
并将所有内容放在同一行上) -
如果使用 Powershell,请将
-D
参数用双引号括起来,例如"-DprojectArtifactId=spring-boot-properties-quickstart"
此命令生成一个项目并导入 spring-boot-properties
扩展。
如果您已经配置了 Quarkus 项目,可以通过在项目根目录中运行以下命令将 spring-boot-properties
扩展添加到您的项目中
quarkus extension add spring-boot-properties
./mvnw quarkus:add-extension -Dextensions='spring-boot-properties'
./gradlew addExtension --extensions='spring-boot-properties'
这会将以下内容添加到您的构建文件中
<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";
}
}
注入属性
创建一个新类 src/main/java/org/acme/spring/boot/properties/GreetingProperties.java
,其中包含一个 message 字段
package org.acme.spring.boot.properties;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties("greeting")
public class GreetingProperties {
public String text;
}
这里 text
字段是 public 的,但它也可以是带有 getter 和 setter 的 private 字段,或者只是接口中的 public 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;
}
}
运行测试以验证应用程序是否仍然正常运行。
打包并运行应用程序
使用以下命令在开发模式下运行应用程序
quarkus dev
./mvnw quarkus:dev
./gradlew --console=plain quarkusDev
在浏览器中打开 https://:8080/greeting。
更改配置文件会立即反映出来。
与往常一样,可以使用以下命令打包应用程序
quarkus build
./mvnw install
./gradlew build
并使用 java -jar target/quarkus-app/quarkus-run.jar
执行。
您还可以使用以下命令生成原生可执行文件
quarkus build --native
./mvnw install -Dnative
./gradlew build -Dquarkus.native.enabled=true
默认值
现在让我们添加一个问候语后缀,我们将为其设置一个默认值。
具有默认值的属性可以在配置文件中像任何其他属性一样配置。但是,如果属性未在配置文件中定义,则将使用默认值。
继续并将新字段添加到 GreetingProperties
类
package org.acme.spring.boot.properties;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties("greeting")
public class GreetingProperties {
public String text;
public String suffix = "!";
}
并更新 GreetingResource
及其测试 GreetingResourceTest
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!"));
}
}
运行测试以验证更改。
可选值
具有可选值的属性是标准属性和具有默认值的属性之间的中间地带。虽然配置文件中缺少属性不会导致您的应用程序失败,但它仍然不会设置值。我们使用 java.util.Optional
类型来定义此类属性。
将可选的 name
属性添加到 GreetingProperties
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;
}
并更新 GreetingResource
及其测试 GreetingResourceTest
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!"));
}
}
运行测试以验证更改。
分组属性
现在我们的 GreetingProperties
类中有三个属性。虽然 name
可以被认为更像是一个运行时属性(并且将来可以作为 HTTP 查询参数传递),但 text
和 suffix
用于定义消息模板。让我们将这两个属性分组到一个单独的内部类中
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 = "!";
}
}
这里的 Message
属性类被定义为一个内部类,但它也可以是一个顶级类。
拥有这样的属性组可以为您的配置带来更多的结构。当属性数量增长时,这尤其有用。
由于添加了类,我们的属性名称已更改。让我们更新属性文件和 GreetingResource
类。
# 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;
}
}