使用Spring Boot属性API访问应用程序属性
If you prefer to use Spring Boot @ConfigurationProperties
annotated class to access application properties instead of
@ConfigMapping
or a MicroProfile @ConfigProperty
approach, you can do that with this extension.
Spring Boot @ConfigurationProperties 有一些限制。例如,不支持 Map 注入。你可以考虑使用 将配置映射到对象 。
|
先决条件
完成这个指南,你需要:
-
大概15分钟
-
编辑器
-
JDK 17+ installed with
JAVA_HOME
configured appropriately -
Apache Maven 3.9.8
-
如果你愿意的话,还可以选择使用Quarkus CLI
-
如果你想构建原生可执行程序,可以选择安装Mandrel或者GraalVM,并正确配置(或者使用Docker在容器中进行构建)
解决方案
我们建议您按照下一节的说明逐步创建应用程序。然而,您可以直接转到已完成的示例。
克隆 Git 仓库: git clone https://github.com/quarkusio/quarkus-quickstarts.git
,或者下载一个 存档 。
The solution is located in the spring-boot-properties-quickstart
directory.
创建Maven项目
首先,我们需要一个新的项目。使用以下命令创建一个新项目:
For Windows users:
-
If using cmd, (don’t use backward slash
\
and put everything on the same line) -
If using Powershell, wrap
-D
parameters in double quotes e.g."-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
First, create a GreetingResource
Jakarta REST resource in the
src/main/java/org/acme/spring/boot/properties/GreetingResource.java
file that looks like:
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
类:
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;
}
}
运行测试以验证应用程序是否仍能正常运行。
打包并运行该应用程序
在开发模式下运行该应用程序:
quarkus dev
./mvnw quarkus:dev
./gradlew --console=plain quarkusDev
在你的浏览器中打开 http://localhost: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
默认值
现在,让我们为greeting 添加一个后缀,我们将为其设置一个默认值。
具有默认值的属性可以像其他属性一样在配置文件中被配置。然而,如果该属性没有在配置文件中被定义,则将使用默认值。
继续在 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
类型来定义这种属性。
在 GreetingProperties
中添加一个可选的 name
属性:
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;
}
}