第一个应用#
应用结构#
端点 -> 资源 -> 服务
依赖结构#
Quarkus BOM的导入,允许省略不同Quarkus依赖的版本
1
2
3
4
5
6
7
8
9
10
11
12
|
<dependencyManagement>
<dependencies>
<dependency>
<groupId>${quarkus.platform.group-id}</groupId>
<artifactId>${quarkus.platform.artifact-id}</artifactId>
<version>${quarkus.platform.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
|
看到 quarkus-maven-plugin ,负责应用程序的打包,也提供开发模式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
<build>
<plugins>
<plugin>
<groupId>${quarkus.platform.group-id}</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<version>${quarkus.platform.version}</version>
<extensions>true</extensions>
<executions>
<execution>
<goals>
<goal>build</goal>
<goal>generate-code</goal>
<goal>generate-code-tests</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
|
Gradle同理
Platform引入QuarkusBOM
1
2
3
4
5
6
7
| val quarkusPlatformGroupId: String by project
val quarkusPlatformArtifactId: String by project
val quarkusPlatformVersion: String by project
dependencies {
implementation(enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}"))
}
|
Quarkus插件
1
2
3
| plugins {
id("io.quarkus")
}
|
Rest依赖
1
2
3
4
5
|
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-rest</artifactId>
</dependency>
|
1
| implementation("io.quarkus:quarkus-rest")
|
代码结构#
使用Quarkus,不需要创建一个 Application
类。它支持这么做,但不是必须的。此外,只有一个资源的实例被创建,而不是每个请求一个。你可以使用不同的 *Scoped 注解(
ApplicationScoped , RequestScoped , 等等)来配置。
Resource
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| package org.acme.getting.started;
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("/hello")
public class GreetingResource {
@Inject
GreetingService service;
@GET
@Produces(MediaType.TEXT_PLAIN)
@Path("/greeting/{name}")
public String greeting(String name) {
return service.greeting(name);
}
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "hello";
}
}
|
Service/Bean
1
2
3
4
5
6
7
8
9
10
11
| package org.acme.getting.started;
import jakarta.enterprise.context.ApplicationScoped;
@ApplicationScoped
public class GreetingService {
public String greeting(String name) {
return "hello " + name;
}
}
|
运行Quarkus#
1
2
3
4
5
6
7
8
| #CLI
quarkus dev
#MAVEN
./mvnw quarkus:dev
#GRADLE
./gradlew --console=plain quarkusDev
|
依赖注入#
创建Bean
1
2
3
4
5
6
7
8
9
10
11
| package org.acme;
import jakarta.enterprise.context.ApplicationScoped;
@ApplicationScoped//声明Bean
public class GreetingService {
public String greeting(String name) {
return "hello " + name;
}
}
|
注入Bean
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| package org.acme;
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("/hello")
public class GreetingResource {
@Inject//注入Bean
GreetingService service;
@GET
@Produces(MediaType.TEXT_PLAIN)
@Path("/greeting/{name}")
public String greeting(String name) {
return service.greeting(name);
}
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "Hello from Quarkus REST";
}
}
|
测试依赖
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<dependencys>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
</dependencys>
|
maven还需要额外配置插件
1
2
3
4
5
|
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>${surefire-plugin.version}</version>
</plugin>
|
maven还需要额外设置Surefire Maven Plugin 的版本,因为默认版本不支持JUnit 5:
1
2
3
4
5
|
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>${surefire-plugin.version}</version>
</plugin>
|
1
2
| testImplementation("io.quarkus:quarkus-junit5")
testImplementation("io.rest-assured:rest-assured")
|
测试代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
| import io.quarkus.test.junit.QuarkusTest;
import org.junit.jupiter.api.Test;
import java.util.UUID;
import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.is;
@QuarkusTest
public class GreetingResourceTest {
@Test
public void testHelloEndpoint() {
given()
.when().get("/hello")
.then()
.statusCode(200)
.body(is("Hello from Quarkus REST"));
}
@Test
public void testGreetingEndpoint() {
String uuid = UUID.randomUUID().toString();
given()
.pathParam("name", uuid)
.when().get("/hello/greeting/{name}")
.then()
.statusCode(200)
.body(is("hello " + uuid));
}
}
|
可以直接使用test命令运行测试
默认情况下,测试将在端口 8081 上运行,以便不与正在运行的应用程序冲突。我们自动将RestAssured配置为使用该端口。如果你想使用不同的客户端,你应该使用
@TestHTTPResource 注释,直接将测试应用程序的URL注入到测试类的一个字段中。这个字段的类型可以是 String , URL 或 URI
。这个注解也可以给测试路径一个值。例如,如果我想测试一个映射到 /myservlet 的Servlet,只需在测试中添加以下内容:
1
2
3
|
@TestHTTPResource("/myservlet")
URL testUrl;
|
测试端口可以通过 quarkus.http.test-port 配置属性来控制。Quarkus还创建了一个名为 test.url 的系统属性,在不能使用注入的情况下被设置为基本测试URL。
1
2
3
4
5
6
| #CLI
quarkus build
#Maven
./mvnw install
#Gradle
./gradlew build
|
getting-started-1.0.0-SNAPSHOT.jar - 它只包含项目的类和资源,是Maven构建时产生的常规组件——它是不可运行的jar。
quarkus-app 目录,其中包含 quarkus-run.jar jar文件是一个可执行的 jar 。请注意,它不是 über-jar ,因为依赖项目被复制到
quarkus-app/lib/ 的子目录中。
使用以下方式运行该应用程序。 java -jar target/quarkus-app/quarkus-run.jar
如果你想把你的应用程序部署到某个地方(通常是在一个容器中),你需要部署整个 quarkus-app 目录。
配置Banner#
默认情况下,当Quarkus应用程序启动时(在常规或开发模式下),它将显示ASCII艺术横幅。可以通过在 application.properties 中设置
quarkus.banner.enabled=false 、设置 -Dquarkus.banner.enabled=false Java系统属性或将 QUARKUS_BANNER_ENABLED 环境变量设置为
false 来禁用横幅。此外,用户可以通过将横幅文件放在 src/main/resources 中并在 application.properties 中配置
quarkus.banner.path=name-of-file 来提供自定义横幅。
基础知识#
基本注解#
quarkus注解 | spring注解 | 说明 | 注解位置 |
---|
@GET/@POST/@PUT/@DELETE | @GetMapping/@PostMapping/@PutMapping/@DeleteMapping | 注明请求方式 | 方法注解 |
@HEAD | @RequestMethod(method = RequestMethod.HEAD) | 请求一个与Get相同的请求,但没有响应体 | 方法注解 |
@OPTIONS | @RequestMethod(method = RequestMethod.OPTIONS) | 描述目标资源的通信选项 | 方法注解 |
@Path | @RequestMapping | 类/方法中处理方法的URL的基本路径 | 类/方法注解 |
@Produces | @RequsetMapping的生产属性 | 资源生成输出类型 | 类/方法注解 |
@Consumes | @RequsetMapping的消费属性 | 资源使用的媒体类型 | 类/方法注解 |
@PathParam | @PathVariable | URL路径变量 | 方法参数 |
@QueryParam | @RequestParam | 查询参数 | 方法参数 |
@FormParam | @RequestParam | Form参数 | 方法参数 |
@HeadParam | @RequestHeader | Head值 | 方法参数 |
@CookieParam | @CookieValue | Cookie值 | 方法参数 |
@MatrixParam | @MatrixVariable | Matrix参数 | 方法参数 |
无 | @RequsetBody | 请求体对象 | 方法参数 |
@Context | 无(直接在参数中写入对象即可) | 注入上下文信息 | 方法参数 |
@ApplicationScope | @Component | 指定容器管理Bean,设置为应用级别单例 | 类注解 |
@Inject | @Autowired | 注入Bean | 属性注解 |
@ConfigProperty | @Value | 配置属性注入 | 属性注解 |
@QuarkusMain | @Application | 程序入口点 | 类注解 |