第2章 Quarkus 开发初探
2.1 开发hello world微服务全过程
下面基于Quarkus 开发一个简单的hello world应用程序。需要在笔记本电脑或开发主机上安装以下工具软件:Git、Java™ JDK 1.8或以上版本、开发者熟悉的 Java开发 IDE工具(本书选择的是Eclipse)、Maven 3.6.2或以上版本。
2.1.1 3种开发方式
第1种方式,使用UI实现
进入Quarkus 自动生成代码项目UI界面(如图2-1所示),可以手动创建Quarkus 项目。
图2-1 Quarkus 自动生成代码项目UI界面
在这个界面上,可以通过3个步骤来初始化一个Quarkus 项目。
(1)界面中提供了 Quarkus 应用程序开发的指导,也给出了其扩展生态系统。首先要定义Group名称,其次要定义 Artifact,最后选择构建模式,有 Maven和 Gradle两种构建模式,在这里选择Maven构建模式。
(2)选择扩展组件(Selected Extensions),即应用程序要用到的扩展组件,可选列表中现阶段 Quarkus 所支持的扩展组件。可以选择多个扩展组件,其中对这些扩展组件进行了分类,如图2-2所示。
图2-2 选择扩展组件
现阶段扩展组件的分类包括 Web、Data、Messaging、Core、Reactive、Cloud、Observability、Security、Integration、Business Automation、Serialization、Miscellaneous、Compatibility等14个大类,包括上百个Quarkus 扩展组件。
(3)选择好扩展组件后,单击“Generate your application”,应用程序源码就会打包下载到本地目录。
这是生成一个典型的 Maven工程项目的结构,典型的 Maven工程项目把 Quarkus 扩展组件添加到pom.xml的项目依赖项中;进行扩展配置、引导并将框架或技术集成到Quarkus 应用程序中;还负责给 GraalVM 提供正确的信息,以便应用程序能够在本机进行编译。这样开发者就可以初始化Maven工程项目并开始自己后续的编程任务了。
第2种方式,写命令文件实现
也可以通过 Maven 的命令来初始化 Quarkus 程序。如果使用的是 Windows 的命令行窗口,可以写如下命令:
io.quarkus:quarkus-maven-plugin:1.11.1.Final 表示构建本项目的 Quarkus 核心版本,DprojectGroupId 表示构建本项目的 GroupId,而 DprojectArtifactId 表示构建本项目的ArtifactId,Dversion表示本项目的版本,DclassName表示生成本项目源码资源的整个限定名,Dpath表示生成本项目资源的路径。
注意:尖括号后面不能有其他字符(包括空格),否则命令不能生效。
如果使用的是PowerShell终端,可以写如下命令:
注意:在每行后有一个符号“`”。
如果是Linux系统,其Bash Shell终端的命令如下:
注意:在每行后有一个符号“\”。
上述 3 种命令实现的效果都一样,生成的文件与 quarkus.io 界面相同,都是一个典型的Maven工程项目的结构。
第3种方式,下载源码实现
导入Maven工程项目,可以从GitHub上克隆预先准备好的示例代码:
该程序位于“010-quarkus-hello”目录中,是一个Maven工程项目。
2.1.2 编写程序内容及说明
这是一个Maven工程项目,可以直接把它导入IDE(通过如图2-3所示的Eclipse工具)。
图2-3 程序界面图
这个工程项目包含了几个文件,即 application.properties 配置文件、pom.xml 文件和源码文件。
打开 pom.xml 文件,其 dependencyManagement 属性部分依赖于 quarkus-universe-bom 文件,这带来了一个优点,即可以忽略配置不同 Quarkus 版本依赖的麻烦工作,同时可以避免由于依赖组件的版本选择不当带来的冲突问题。相关代码如下:
在上述文件中,quarkus-plugin.version和quarkus.platform.version的版本都是1.11.1.Final。
在pom.xml中,还可以看到quarkus-plugin.version属性,将其赋值给quarkus-maven-plugin插件。该插件负责打包应用、管理开发模式及导入依赖等辅助环节。
针对该工程项目,其pom.xml文件有以下依赖:
在该程序中,只有一个com.iiit.quarkus.sample.hello.HelloResource类负责暴露/hello服务,还有配套的简单测试类,其代码如下:
程序遵循JAX-RS规范,相关注解说明如下。
①@Path("/hello")——当 Path标注一个 Java类时,表明该 Java类是一个资源类。资源类必须使用该注解,表示路径可以通过/hello来访问。
②@GET——指明接收HTTP请求的方式属于get方式。
③@Path("/{name}")——当Path标注method时,表示具体的请求资源的路径。
④@Produces(MediaType.TEXT_PLAIN)——指定 HTTP响应的 MIME类型,默认是*/*,表示任意的MIME类型。这里的类型是TEXT_PLAIN。
如果对 javax.ws.rs-api 比较熟悉的话,理解起来会比较容易。程序实现的功能比较简单。HelloResource类有两个方法:当通过HTTP访问时,答复是hello world;当带着参数访问时,答复是hello加上参数。
应用程序启动后,可以通过浏览器URL(http://localhost:8080/hello)访问服务。
2.1.3 测试hello world微服务
本节介绍如何构建Quarkus 的测试程序。
对于测试程序,其Maven依赖组件主要包括测试组件和与测试HTTP服务相关的组件。
1.对pom.xml进行设置
通过Maven执行单元测试,需要引入相应的依赖组件:
若要测试HTTP服务,还需要引入Rest Assured依赖:
Quarkus 支持JUnit 5测试,因此,必须设置Surefire Maven插件的版本,因为默认版本不支持JUnit 5。
我们还设置了 java.util.logging 属性,以确保测试将使用正确的日志管理器和 maven.home来自定义配置${maven.home}/conf/settings.xml应用。
以上只说明了Quarkus 对Maven构建工具的支持。除此之外,Quarkus 也支持Gradle工具的构建。
2.单元测试示例
使用 HTTP 直接测试 REST 服务,打开程序源码文件 src/test/java/com/iiit/quarkus/sample/hello/HelloResourceTest.java,其代码如下:
可以看到测试方法testHelloEndpoint有两个主要功能,解释如下。
①访问/hello REST服务,测试成功的HTTP服务的返回状态码为200。
②带参数访问/hello REST服务,测试返回的报文是否是hello world。
3.运行测试程序
用简单的Maven命令mvn clean test就可以进行测试,默认的测试端口是8080。当出现如图2-4所示的界面时,表示测试成功。
图2-4 测试成功界面
2.1.4 运行程序及打包
1.在开发环境下运行程序
在当前工程项目目录下打开命令行窗口并执行命令 mvnw compile quarkus:dev或者 mvnw quarkus:dev,可以看到Quarkus 服务启动界面,如图2-5所示。
图2-5 Quarkus 服务启动界面
在服务启动完毕后,将打开一个命令行窗口,可以执行下面的curl命令来验证应用是否正常运行:
输出结果:hello world。
2.打包jar应用并运行程序
Quarkus 应用程序可以被打包成JVM可执行的jar文件。
在当前工程项目目录下打开命令行窗口并执行命令 mvn clean package 或者/mvnw clean package。运行命令后,会在 target/目录下生成一个可执行的 jar文件,名为 010-quarkus-hello-1.0-SNAPSHOT-runner.jar。这可不是一个 uber-jar 文件,相关依赖文件已经被复制到 target/lib目录下。
运行可执行的jar文件,命令如下:
这里用-Dquarkus.http.port=8081 命令启用了 8081 端口,可以避免同在线编程示例使用的8080端口发生冲突,如图2-6所示。
图2-6 打包并运行打包文件
以上是构建一个基本的Quarkus 应用程序的过程,这和开发普通的Java应用没有区别。应用会被打包成可执行的 jar文件,并且快速启动。这个 jar文件可以像任何常见的可执行 jar文件一样使用,比如直接运行或把它封装成Linux容器镜像。
3.创建原生可执行程序并运行
要创建原生可执行程序,可在当前工程项目目录下打开命令行窗口并执行命令 mvnw package-Pnative来创建原生可执行程序。
如果没有安装 GraalVM,则只能在本机容器中运行,命令为 mvnw package-Pnative-Dquarkus.native.container-build=true。
然后可以使用/target/010-quarkus-hello-1.0-SNAPSHOT-runner来执行原生可执行程序。