Vert.x 导论之一:第一个Vert.x 3 应用

你听有些人说Vert.x很酷炫,你可能想亲自尝试下。于是你很自然的想到“我该从哪里起步?”那么这个帖子就是为你准备的。包含了如何构建一个很简单的vert.x应用,如何测试,打包并执行。总之,在你开发自己的开创性应用前所需要知道的一切。

这个帖子中的代码可以在github(https://github.com/cescoffier/my-vertx-first-app)上找到,本文同时也是Vertx 导论系列的一部分。这部分代码在post-1分支中。

让我们开工吧

首先,我们使用Apache Maven来创建项目,但你也可以使用Gradle或者你喜欢的其他构建工具。你可以使用Maven自带的jar模板原型来创建项目结构,不过事实上,你只需要有如下目录结构的一个目录:
1.一个 src/main/java目录
2.一个 src/test/java目录
3.一个pom.xml文件
所以,你的项目将会是如下结构:

.
├── pom.xml
├── src
│   ├── main
│   │   └── java
│   └── test
│       └── java

我们创建如下内容的pom.xml文件。


  4.0.0
  io.vertx.blog
  my-first-app
  0.0.1-SNAPSHOT

  
    
      io.vertx
      vertx-core
      3.5.1
    
  

  
    
      
        maven-compiler-plugin
        3.5.1
        
          1.8
          1.8
        
      
    
  


pom.xml文件的内容非常明确:

  • 声明了 vertx-core的依赖
  • 配置maven-compiler-plugin使用java8
    第二条很重要,Vert.x 应用需要Java 8。

让我们编码吧

我们准备好了pom.xml文件。现在开始编码工作。。。创建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 fut) {
    vertx
        .createHttpServer()
        .requestHandler(r -> {
          r.response().end("

Hello from my first " + "Vert.x 3 application

"); }) .listen(8080, result -> { if (result.succeeded()) { fut.complete(); } else { fut.fail(result.cause()); } }); } }

这只是个很普通的应用。该类继承了AbstractVerticle。在Vert.x的世界里,一个verticle是一个组件。通过继承AbstractVerticle,该类可以访问并使用vertx字段。

当verticle被部署后start方法被调用。我们还能实现一个stop方法,在本例中Vert.x为我们做了默认的垃圾回收。start方法会接收到一个Future对象,Future对象可以用来通知Vert.x我们的开始序列已经执行完毕或者执行报错。Vert.x具有异步/非阻塞的特性。verticle被部署时不会一直等待到start方法被执行完成。所以,Future参数对通告start方法执行完毕而言很重要。

start方法创建了一个HTTP服务器还在其基础上添加了一个请求处理器。该请求处理器是一个lambda表达式,被放入requestHandler方法,每当HTTP服务器接收到一个请求时都会被调用。我们这里只是回复Hello。最后,该服务器被绑定在8080端口。由于这可能失败(因为这个端口可能早已被占用),我们传入另一个lambda表达式来检查该连接是否成功。如上所述,如果成功就调用fut.complete否则调用fut.fail来报告失败。

使用如下命令来编译应用:

mvn clean compile

顺利的话,应该能正常执行。

让我们添加测试单元吧

能开发一个应用很好,但是再小心也不为过,所以我们要添加测试。这个测试使用JUnit和vertx-unit -一个随vert.x发布的框架,目的在于让vert.x应用的测试更加方便。

打开pom.xml文件,添加如下两个依赖:


  junit
  junit
  4.12
  test


  io.vertx
  vertx-unit
  3.5.1
  test

现在创建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方法中,我们创建了一个Vertx的实例并部署了我们的verticle。你可能注意到不同与传统的JUnit @Before方法,我们的Before方法接收一个TestContext。该对象辅助我们进行异步测试。比方说,当我们部署verticle时,verticle异步启动,在verticle正常启动前我们不能做任何检测。所以,在 deployVerticle方法的第二个参数位置,我们传入一个结果处理器:context.asyncAssertSuccess()。如果verticle没有正常启动,这个方法会失败。此外,这个方法会一直等到verticle完成了启动序列。记住,在verticle中,我们调用fut.complete()。所以context.asyncAssertSuccess()方法会一直等待直到fut.complete()被调用,并且如果中途出现异常,就让测试失败。

tearDown方法就很直观,就是结束我们创建的vertx实例。

现在来看我们应用的测试:testMyApplication方法。该测试向应用发出请求并检测结果。由于发出请求和接收响应都是异步的,我们需要有一种方式来控制这一点。和setUptearDown方法一样,test方法接收一个TestContext对象。我们从这个对象中创建一个异步处理器(async),当测试完成时使用async.complete()通知测试框架测试完成。

一旦async处理器被创建好,我们创建一个HTTP客户端并用getNow()方法向我们的应用发出一个HTTP请求(getNow是get(...).end()的缩写)。响应由一个lambda表达式处理。在这个lambda表达式中我们通过给处理器方法传入另一个lambda表达式来获取响应体。body参数就是响应体(是buffer对象)。我们检测确认响应体中含有"Hello"字符串并声明测试结束。

我们再说下断言,不像传统的JUnit测试,这里使用context.assert...事实上,如果断言失败,该方法会马上终止测试。由于Vert.x应用的异步特性总是使用这些断言方法很重要。

我们的测试可以用IDE或者Maven发起:

mvn clean test

打包

我们来总结一下,目前为止,我们有一个应用和一个测试,现在我们来打包应用。在这个贴子里,我们把这个应用打包成fat jar。一个fat jar 是一个独立可执行jar文件,含有运行应用所需要的所有依赖。由于只有一个文件,这种方式打包Vert.x应用很方便,也利于执行。

为了创建一个fat jar,编辑pom.xml文件在前添加如下代码片段:


  org.apache.maven.plugins
  maven-shade-plugin
  2.4.3
  
    
      package
      
        shade
      
      
        
          
            
              io.vertx.core.Starter
              io.vertx.blog.first.MyFirstVerticle
            
          
        
        
        ${project.build.directory}/${project.artifactId}-${project.version}-fat.jar
      
    
  

上面使用maven-shade-plugin 来创建fat jar. 在manifestEntries 中指定了verticle的名字。你可能琢磨Starter类从何而来,事实上这个类来自vert.x。该类将会创建vertx实例并部署verticle。

配置好这个插件后,我们执行如下命令:

mvn clean package

该命令将创建 target/my-first-vertx-app-0.0.1-SNAPSHOT-fat.jar 文件,该文件包含我们的应用以及所有相关依赖(包括vert.x本身)。

执行我们的应用吧

有一个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来开发一个简单应用,测试打包并运行。你现在掌握了用Vert.x 3构建神奇系统的基础。下一次内容是配置我们的应用。

你可能感兴趣的:(Vert.x 导论之一:第一个Vert.x 3 应用)