美文网首页
Vert.x 导论之一:第一个Vert.x 3 应用

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

作者: luciensun | 来源:发表于2018-05-16 18:07 被阅读0次

    你听有些人说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文件。

    <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文件。现在开始编码工作。。。创建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方法被调用。我们还能实现一个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文件,添加如下两个依赖:

    <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>
    

    现在创建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文件在</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 来创建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 应用

          本文链接:https://www.haomeiwen.com/subject/vkjjdftx.html