我的第一个Vert.x 3 应用

如果,你听到有人说Vert.x 是牛逼的。非常好!但是你自己想要尝试的话,Ok great,那么下一个问题自然是“从哪里开始?”,这篇文章是一个很好的起点。文章展示了怎么构建一个非常简单的 vert.x 应用(这没什么大不了的),怎样测试和执行vert.x应用。

文章里提到的代码在github

开始

首先,创建一个项目,在这篇文章中使用Apache Maven,当然你可以使用Gradle 或者其他工具,使用Maven jar archetype 创建结构,但基本上只需要一个目录。

  • src/main/java 目录
  • src/test/java 目录
  • pom.xml 文件

会得到一个像这样的结构

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

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>name.quanke.study.vertx.first</groupId>
  <artifactId>my-first-app</artifactId>
  <version>1.0-SNAPSHOT</version>

  <dependencies>
    <dependency>
      <groupId>io.vertx</groupId>
      <artifactId>vertx-core</artifactId>
      <version>3.0.0</version>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.3</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
        </configuration>
      </plugin>
    </plugins>
  </build>

</project>

这个 pom.xml 文件非常简单:

  • 声明了一个 vertx-core 依赖
  • 配置了maven-compiler-plugin 插件(使用的是Java 8).

第二点非常重要,Vert.x 只支持Java 8

编码!

OK,我们已经创建了一个pom.xml 文件,接下来正式开始编码,创建 src/main/java/name/quanke/study/vertx/first/MyFirstVerticle.java文件,内容如下:

package name.quanke.study.vertx.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就是组件(是Vert.x的之行单元),通过继承AbstractVerticle类,获得vertx的入口。

verticle部署后会调用start方法,我们也能实现 stop 方法,在这个方法里回收资源,start方法接收Future对象的参数,可以告诉用户是执行完成还是报出错误,Vert.x是异步执行的,运行的时候不会等到start方法执行完成,所以 Future 参数是非常重要的,可以通知是否已经执行完成。

start方法里创建了一个HTTP 服务和一个请求处理器(handler),这个请求处理器使用lambda表达式,通过requestHandler方法,每次服务器收到请求,都会返回“Hello。。。”(也没有什么其他可以告诉你的东西了。。。),最后服务器绑定了一个8080端口,这里可能会失败(因为8080端口可能被使用了),通过lambda表达式检查是否连接成功,就想上面说的,调用fut.complete表示成功,调用 fut.fail 报告失败。

使用下面的命令尝试着编译应用(首先你要安装好了maven,此命令在pom.xml目录下执行,知道使用maven的都懂得):

mvn clean compile

如果幸运,编译应该是成功的。

应用就编写到这里,是不是很简单?

测试

应用开发完成了,但是我们从来都不是很认真的,所有我们需要测试一下,测试使用JUnitvertx-unit

打开pom.xml文件,增加两个依赖(dependencies):

<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.0.0</version>
  <scope>test</scope>
</dependency>

创建 src/main/java/name/quanke/study/vertx/first/MyFirstVerticleTest.java 文件

package name.quanke.study.vertx.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();
      });
    });
  }
}

在这里使用JUnit测试verticle,也会使用到 vertx-unit 自定义的runnervert.x-unit很容易测试异步的vert.x应用。

setUp方法里,创建了一个Vertx实例,deployverticle ,你可能已经注意到了,这与传统JUnit@Before不一样,它接收了一个TestContext参数,TestContext对象让我们可以控制异步的测试,例如:当我们deploy了异步verticle,多个Vertx实例相互作用时,不能检测它的正确性,deployVerticle方法的第二个参数返回一个handler:context.asyncAssertSuccess(),如果verticle的状态是失败,那这个测试就是失败的,此外会等待verticle完成启动,还记得,在verticle里,我们调用了fut.complete()方法,直到等到调用fut.complete()方法才返回状态。

tearDown方法比较简单,负责回收我们创建的vertx对象。

现在我们看一下测试应用的testMyApplication方法,给应用发出请求并且拦截一个返回,发出请求和接收答复都是异步的,我们需要一种方法来控制,setUptearDown方法接收一个TestContext对象,当这个测试完成的时候,通过我们这个对象创建的异步的处理器(async),通知测试框架(使用async.complete()

像这样,一个异步处理器创建好了,我们使用getNow()方法(getNow()方法是get(...).end()的捷径),创建一个HTTP客户端和发一个HTTP请求给我们的应用,响应使用lambda处理,通过另一个lambdahandler方法接收一个response body,这个body参数是这个response body(如buffer对象),检测body是否等于“Hello”字符串,并且宣布测试完成(async.complete())。

让我们花一个分钟的时间提一下这个断言,不像传统的使用context.assert...断言,如果断言失败,它会立即中断测试,因为Vert.x 程序各方面都是异步的,所以使用这种方式断言测试很重要。

可以使用IDE或者Maven运行测试:

mvn clean test

打包

总结一下,我们有了应用程序和测试,接下来,给应用打包,在这篇文章中我们把应用打 成fat jar包,一个 fat jar包是一个可以独立执行的jar文件,它包含所有的运行程序所需要的依赖,Vert.x使用这种打包的方式非常方便,仅仅只有一个文件,这使它非常容易执行。

创建一个 fat jar 便捷pom.xml文件,把下面的的代码增加到</plugins>标签之前:

<plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>2.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>name.quanke.study.vertx.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 创建fat jar。在manifestEntries标签里声明我们的verticle,你也许不知道从哪里来的Starter类,实际上,它是在vertx实例化和部署verticle的时候就有创建。

这个插件的配置就是这样,我们执行:

mvn clean package

应该会创建一个target/my-first-app-1.0-SNAPSHOT-fat.jar,里面嵌入了应用所有的依赖(包含vert.x自己)。

执行

嗯,很高兴拥有一个 fal jar,但我们希望看到我们的应用程序的运行!正如上面所说,多亏了fat jar包装,运行vert.x应用程序是容易的:

java -jar target/my-first-app-1.0-SNAPSHOT-fat.jar

然后,打开浏览器访问 http://localhost:8080。

CTRL+C停止应用运行。

总结

这个Vert.x 3速成班告诉你,怎么使用Vert.x 3开发一个简单的应用,怎么测试、打包和运行,现在知道了在Vert.x 3 上任意创建令人惊奇的系统。接下来的时间看看怎么配置我们的应用

Happy coding & Stay tuned !

本人英语比较烂,建议看原文