你聽有些人說Vert.x很酷炫衡奥,你可能想親自嘗試下涂籽。于是你很自然的想到“我該從哪里起步么抗?”那么這個帖子就是為你準備的毅否。包含了如何構建一個很簡單的vert.x應用,如何測試蝇刀,打包并執(zhí)行螟加。總之吞琐,在你開發(fā)自己的開創(chuàng)性應用前所需要知道的一切仰迁。
這個帖子中的代碼可以在github(https://github.com/cescoffier/my-vertx-first-app)上找到,本文同時也是Vertx 導論系列的一部分顽分。這部分代碼在post-1分支中。
讓我們開工吧
首先施蜜,我們使用Apache Maven來創(chuàng)建項目卒蘸,但你也可以使用Gradle或者你喜歡的其他構建工具。你可以使用Maven自帶的jar模板原型來創(chuàng)建項目結構翻默,不過事實上缸沃,你只需要有如下目錄結構的一個目錄:
1.一個 src/main/java目錄
2.一個 src/test/java目錄
3.一個pom.xml文件
所以,你的項目將會是如下結構:
.
├── pom.xml
├── src
│ ├── main
│ │ └── java
│ └── test
│ └── java
我們創(chuàng)建如下內容的pom.xml文件修械。
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>io.vertx.blog</groupId>
<artifactId>my-first-app</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-core</artifactId>
<version>3.5.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
pom.xml文件的內容非常明確:
- 聲明了
vertx-core
的依賴 - 配置
maven-compiler-plugin
使用java8
第二條很重要趾牧,Vert.x 應用需要Java 8。
讓我們編碼吧
我們準備好了pom.xml文件】衔郏現(xiàn)在開始編碼工作翘单。。蹦渣。創(chuàng)建src/main/java/io/vertx/blog/first/MyFirstVerticle文件哄芜,內容如下:
package io.vertx.blog.first;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Future;
public class MyFirstVerticle extends AbstractVerticle {
@Override
public void start(Future<Void> fut) {
vertx
.createHttpServer()
.requestHandler(r -> {
r.response().end("<h1>Hello from my first " +
"Vert.x 3 application</h1>");
})
.listen(8080, result -> {
if (result.succeeded()) {
fut.complete();
} else {
fut.fail(result.cause());
}
});
}
}
這只是個很普通的應用。該類繼承了AbstractVerticle
柬唯。在Vert.x的世界里认臊,一個verticle是一個組件。通過繼承AbstractVerticle
锄奢,該類可以訪問并使用vertx
字段失晴。
當verticle被部署后start
方法被調用。我們還能實現(xiàn)一個stop
方法拘央,在本例中Vert.x為我們做了默認的垃圾回收涂屁。start
方法會接收到一個Future
對象,Future
對象可以用來通知Vert.x我們的開始序列已經(jīng)執(zhí)行完畢或者執(zhí)行報錯堪滨。Vert.x具有異步/非阻塞的特性胯陋。verticle被部署時不會一直等待到start
方法被執(zhí)行完成。所以,Future
參數(shù)對通告start方法執(zhí)行完畢而言很重要遏乔。
start
方法創(chuàng)建了一個HTTP服務器還在其基礎上添加了一個請求處理器义矛。該請求處理器是一個lambda表達式,被放入requestHandler
方法盟萨,每當HTTP服務器接收到一個請求時都會被調用凉翻。我們這里只是回復Hello。最后捻激,該服務器被綁定在8080端口制轰。由于這可能失敗(因為這個端口可能早已被占用)胞谭,我們傳入另一個lambda表達式來檢查該連接是否成功垃杖。如上所述,如果成功就調用fut.complete
否則調用fut.fail
來報告失敗丈屹。
使用如下命令來編譯應用:
mvn clean compile
順利的話调俘,應該能正常執(zhí)行。
讓我們添加測試單元吧
能開發(fā)一個應用很好旺垒,但是再小心也不為過彩库,所以我們要添加測試。這個測試使用JUnit和vertx-unit -一個隨vert.x發(fā)布的框架先蒋,目的在于讓vert.x應用的測試更加方便骇钦。
打開pom.xml
文件,添加如下兩個依賴:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-unit</artifactId>
<version>3.5.1</version>
<scope>test</scope>
現(xiàn)在創(chuàng)建src/test/java/io/vertx/blog/first/MyFirstVerticleTest.java文件竞漾,內容如下:
package io.vertx.blog.first;
import io.vertx.core.Vertx;
import io.vertx.ext.unit.Async;
import io.vertx.ext.unit.TestContext;
import io.vertx.ext.unit.junit.VertxUnitRunner;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(VertxUnitRunner.class)
public class MyFirstVerticleTest {
private Vertx vertx;
@Before
public void setUp(TestContext context) {
vertx = Vertx.vertx();
vertx.deployVerticle(MyFirstVerticle.class.getName(),
context.asyncAssertSuccess());
}
@After
public void tearDown(TestContext context) {
vertx.close(context.asyncAssertSuccess());
}
@Test
public void testMyApplication(TestContext context) {
final Async async = context.async();
vertx.createHttpClient().getNow(8080, "localhost", "/",
response -> {
response.handler(body -> {
context.assertTrue(body.toString().contains("Hello"));
async.complete();
});
});
}
}
以上是對verticle的JUnit測試眯搭。該測試使用vertx-unit,所以我們使用一個定制的runner业岁。vertx-unit 方便了異步交互的測試坦仍,而異步交互就是vert.x應用的基礎。
再setUp
方法中叨襟,我們創(chuàng)建了一個Vertx
的實例并部署了我們的verticle繁扎。你可能注意到不同與傳統(tǒng)的JUnit @Before
方法,我們的Before方法接收一個TestContext
糊闽。該對象輔助我們進行異步測試梳玫。比方說,當我們部署verticle時右犹,verticle異步啟動提澎,在verticle正常啟動前我們不能做任何檢測。所以念链,在 deployVerticle
方法的第二個參數(shù)位置盼忌,我們傳入一個結果處理器:context.asyncAssertSuccess()
积糯。如果verticle沒有正常啟動,這個方法會失敗谦纱。此外看成,這個方法會一直等到verticle完成了啟動序列。記住跨嘉,在verticle中川慌,我們調用fut.complete()
。所以context.asyncAssertSuccess()
方法會一直等待直到fut.complete()
被調用祠乃,并且如果中途出現(xiàn)異常梦重,就讓測試失敗。
而tearDown
方法就很直觀亮瓷,就是結束我們創(chuàng)建的vertx
實例琴拧。
現(xiàn)在來看我們應用的測試:testMyApplication
方法。該測試向應用發(fā)出請求并檢測結果嘱支。由于發(fā)出請求和接收響應都是異步的艾蓝,我們需要有一種方式來控制這一點。和setUp
和tearDown
方法一樣斗塘,test方法接收一個TestContext
對象。我們從這個對象中創(chuàng)建一個異步處理器(async
)亮靴,當測試完成時使用async.complete()
通知測試框架測試完成馍盟。
一旦async
處理器被創(chuàng)建好,我們創(chuàng)建一個HTTP客戶端并用getNow()
方法向我們的應用發(fā)出一個HTTP請求(getNow是get(...).end()
的縮寫)茧吊。響應由一個lambda表達式處理贞岭。在這個lambda表達式中我們通過給處理器方法傳入另一個lambda表達式來獲取響應體。body
參數(shù)就是響應體(是buffer
對象)搓侄。我們檢測確認響應體中含有"Hello"
字符串并聲明測試結束瞄桨。
我們再說下斷言,不像傳統(tǒng)的JUnit測試讶踪,這里使用context.assert...
事實上芯侥,如果斷言失敗,該方法會馬上終止測試乳讥。由于Vert.x應用的異步特性總是使用這些斷言方法很重要柱查。
我們的測試可以用IDE或者Maven發(fā)起:
mvn clean test
打包
我們來總結一下,目前為止云石,我們有一個應用和一個測試唉工,現(xiàn)在我們來打包應用。在這個貼子里汹忠,我們把這個應用打包成fat jar淋硝。一個fat jar 是一個獨立可執(zhí)行jar文件雹熬,含有運行應用所需要的所有依賴。由于只有一個文件谣膳,這種方式打包Vert.x應用很方便竿报,也利于執(zhí)行。
為了創(chuàng)建一個fat jar参歹,編輯pom.xml
文件在</plugins>
前添加如下代碼片段:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>io.vertx.core.Starter</Main-Class>
<Main-Verticle>io.vertx.blog.first.MyFirstVerticle</Main-Verticle>
</manifestEntries>
</transformer>
</transformers>
<artifactSet/>
<outputFile>${project.build.directory}/${project.artifactId}-${project.version}-fat.jar</outputFile>
</configuration>
</execution>
</executions>
</plugin>
上面使用maven-shade-plugin 來創(chuàng)建fat jar
. 在manifestEntries
中指定了verticle的名字仰楚。你可能琢磨Starter
類從何而來,事實上這個類來自vert.x犬庇。該類將會創(chuàng)建vertx
實例并部署verticle僧界。
配置好這個插件后,我們執(zhí)行如下命令:
mvn clean package
該命令將創(chuàng)建 target/my-first-vertx-app-0.0.1-SNAPSHOT-fat.jar 文件臭挽,該文件包含我們的應用以及所有相關依賴(包括vert.x本身)捂襟。
執(zhí)行我們的應用吧
有一個fat jar很好,但我們更想看應用運行效果欢峰,如之前所述葬荷,歸功于fat jar打包方式,運行Vert.x應用很簡單:
java -jar target/my-first-vertx-app-0.0.1-SNAPSHOT-fat.jar
然后纽帖,打開瀏覽器宠漩,訪問http://localhost:8080。
想要停止應用懊直,敲擊CTRL+C
扒吁。
結論
這門Vert.x 3速成課展示了如何使用Vert.x 3來開發(fā)一個簡單應用,測試打包并運行室囊。你現(xiàn)在掌握了用Vert.x 3構建神奇系統(tǒng)的基礎雕崩。下一次內容是配置我們的應用。