Vert.x 導論之一:第一個Vert.x 3 應用

你聽有些人說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ā)出請求和接收響應都是異步的艾蓝,我們需要有一種方式來控制這一點。和setUptearDown方法一樣斗塘,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)的基礎雕崩。下一次內容是配置我們的應用

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末融撞,一起剝皮案震驚了整個濱河市盼铁,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌尝偎,老刑警劉巖饶火,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異致扯,居然都是意外死亡趁窃,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進店門急前,熙熙樓的掌柜王于貴愁眉苦臉地迎上來醒陆,“玉大人,你說我怎么就攤上這事裆针∨倌Γ” “怎么了寺晌?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長澡刹。 經(jīng)常有香客問我呻征,道長,這世上最難降的妖魔是什么罢浇? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任陆赋,我火速辦了婚禮,結果婚禮上嚷闭,老公的妹妹穿的比我還像新娘攒岛。我一直安慰自己,他們只是感情好胞锰,可當我...
    茶點故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布灾锯。 她就那樣靜靜地躺著,像睡著了一般嗅榕。 火紅的嫁衣襯著肌膚如雪顺饮。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天凌那,我揣著相機與錄音兼雄,去河邊找鬼。 笑死帽蝶,一個胖子當著我的面吹牛赦肋,可吹牛的內容都是我干的。 我是一名探鬼主播嘲碱,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼局蚀!你這毒婦竟也來了麦锯?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤琅绅,失蹤者是張志新(化名)和其女友劉穎扶欣,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體千扶,經(jīng)...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡料祠,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了澎羞。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片髓绽。...
    茶點故事閱讀 38,646評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖妆绞,靈堂內的尸體忽然破棺而出顺呕,到底是詐尸還是另有隱情枫攀,我是刑警寧澤,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布株茶,位于F島的核電站来涨,受9級特大地震影響,放射性物質發(fā)生泄漏启盛。R本人自食惡果不足惜蹦掐,卻給世界環(huán)境...
    茶點故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望僵闯。 院中可真熱鬧卧抗,春花似錦、人聲如沸棍厂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽谢肾。三九已至迅栅,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間张漂,已是汗流浹背晶默。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留航攒,地道東北人磺陡。 一個月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像漠畜,于是被迫代替她去往敵國和親币他。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,514評論 2 348

推薦閱讀更多精彩內容