支持JDK19虛擬線程的web框架,之二:完整開發一個支持虛擬線程的quarkus應用( 三 )

  • pom.xml的第一處改動如下圖,要確保全部是19

支持JDK19虛擬線程的web框架,之二:完整開發一個支持虛擬線程的quarkus應用

文章插圖
  • 第二處改動 , 是在quarkus-maven-plugin插件中增加額外的配置參數,如下圖紅框

支持JDK19虛擬線程的web框架,之二:完整開發一個支持虛擬線程的quarkus應用

文章插圖
  • 接下來新增配置文件application.properties , 在resources目錄下
quarkus.datasource.db-kind=postgresqlquarkus.datasource.jdbc.max-size=8quarkus.datasource.jdbc.min-size=2quarkus.datasource.username=quarkusquarkus.datasource.password=123456quarkus.datasource.reactive.url=postgresql://192.168.0.1:5432/quarkus_test
  • 開始寫java代碼了 , 首先是啟動類VirtualThreadsDemoApp.java
package com.bolingcavalry;import io.quarkus.runtime.Quarkus;import io.quarkus.runtime.annotations.QuarkusMain;@QuarkusMainpublic class VirtualThreadsDemoApp {public static void main(String... args) {Quarkus.run(args);}}
  • 數據庫對應的model類有兩個,第一個是gender字段的枚舉
package com.bolingcavalry.model;public enum Gender {MALE, FEMALE;}
  • 表對應的實體類
package com.bolingcavalry.model;import io.vertx.mutiny.sqlclient.Row;public class Person {private Long id;private String name;private int age;private Gender gender;private Integer externalId;public String getThreadInfo() {return threadInfo;}public void setThreadInfo(String threadInfo) {this.threadInfo = threadInfo;}private String threadInfo;public Person() {}public Person(Long id, String name, int age, Gender gender, Integer externalId) {this.id = id;this.name = name;this.age = age;this.gender = gender;this.externalId = externalId;this.threadInfo = Thread.currentThread().toString();}public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public Gender getGender() {return gender;}public void setGender(Gender gender) {this.gender = gender;}public Integer getExternalId() {return externalId;}public void setExternalId(Integer externalId) {this.externalId = externalId;}public static Person from(Row row) {return new Person(row.getLong("id"),row.getString("name"),row.getInteger("age"),Gender.valueOf(row.getString("gender")),row.getInteger("external_id"));}}
  • 接下來是操作數據庫的dao類,可見使用操作方式還是很原始的,還要在代碼中手寫SQL,取出也要逐個字段匹配,其實quarkus也支持JPA,只不過本篇使用的是響應式數據庫驅動,所以選用的是Vert.x生成的連接池PgPool
package com.bolingcavalry.repository;import com.bolingcavalry.model.Person;import io.vertx.mutiny.pgclient.PgPool;import io.vertx.mutiny.sqlclient.Row;import io.vertx.mutiny.sqlclient.RowSet;import io.vertx.mutiny.sqlclient.Tuple;import javax.enterprise.context.ApplicationScoped;import javax.inject.Inject;import java.util.ArrayList;import java.util.List;@ApplicationScopedpublic class PersonRepositoryAsyncAwait {@InjectPgPool pgPool;public Person findById(Long id) {RowSet<Row> rowSet = pgPool.preparedQuery("SELECT id, name, age, gender, external_id FROM person WHERE id = $1").executeAndAwait(Tuple.of(id));List<Person> persons = iterateAndCreate(rowSet);return persons.size() == 0 ? null : persons.get(0);}private List<Person> iterateAndCreate(RowSet<Row> rowSet) {List<Person> persons = new ArrayList<>();for (Row row : rowSet) {persons.add(Person.from(row));}return persons;}}
  • 接下來就是前面截圖看到的web服務類VTPersonResource.java,它被注解@RunOnVirtualThread修飾 , 表示收到web請求在虛擬線程中執行響應代碼
package com.bolingcavalry.resource;import com.bolingcavalry.model.Person;import com.bolingcavalry.repository.PersonRepositoryAsyncAwait;import io.smallrye.common.annotation.RunOnVirtualThread;import javax.inject.Inject;import javax.ws.rs.GET;import javax.ws.rs.Path;import javax.ws.rs.PathParam;@Path("/vt/persons")@RunOnVirtualThreadpublic class VTPersonResource {@InjectPersonRepositoryAsyncAwait personRepository;@GET@Path("/{id}")public Person getPersonById(@PathParam("id") Long id) {return personRepository.findById(id);}}
  • 最后是用于對比的常規web服務類PoolPersonResource.java,這個就是中規中矩的在線程池中取一個線程來執行響應代碼
package com.bolingcavalry.resource;import com.bolingcavalry.model.Person;import com.bolingcavalry.repository.PersonRepositoryAsyncAwait;import io.smallrye.common.annotation.RunOnVirtualThread;import javax.inject.Inject;import javax.ws.rs.GET;import javax.ws.rs.Path;import javax.ws.rs.PathParam;@Path("/pool/persons")public class PoolPersonResource {@InjectPersonRepositoryAsyncAwait personRepository;@GET@Path("/{id}")public Person getPersonById(@PathParam("id") Long id) {return personRepository.findById(id);}}

推薦閱讀