如何集成Vert.x到Spring框架中

如何集成Vert.x到Spring框架中

1. 概述

在本中,我们将讨论Spring与Vertx的集成,并利用两个框架各自的优点:强大的Spring整合特性,以及来自Vert.x的reactive single-event loop特性

2. Maven依赖

首先添加相关依赖到pom.xml文件中

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>io.vertx</groupId>
    <artifactId>vertx-web</artifactId>
    <version>3.4.1</version>
</dependency>

注意,我们已经从spring-boot-starter-web中排除了嵌入式Tomcat依赖项,因为我们将使用verticles部署我们的Http服务

3. Spring Vert.x 应用

现在,我们将构建一个部署了两个verticles的案例应用程序。

第一个Verticle将请求路由到处理程序,该处理程序将请求作为消息发送到给定地址。另一个Verticle在给定的地址侦听,并处理请求

3.1 Sender Verticle

ServerVerticle接受HTTP请求并将它们作为消息发送到指定的地址。让我们创建一个ServerVerticle类来扩展AbstractVerticle,并覆盖start()方法来创建我们的HTTP服务器:

@Override
public void start() throws Exception {
    super.start();
 
    Router router = Router.router(vertx);
    router.get("/api/vertx/articles")
      .handler(this::getAllArticlesHandler);
 
    vertx.createHttpServer()
      .requestHandler(router::accept)
      .listen(config().getInteger("http.port", 8080));
}

在服务器请求处理程序中,我们传递了一个路由器对象,它将任何传入的请求重定向到getAllArticlesHandler处理程序:

private void getAllArticlesHandler(RoutingContext routingContext) {
    vertx.eventBus().<String>send(ArticleRecipientVerticle.GET_ALL_ARTICLES, "", 
      result -> {
        if (result.succeeded()) {
            routingContext.response()
              .putHeader("content-type", "application/json")
              .setStatusCode(200)
              .end(result.result()
              .body());
        } else {
            routingContext.response()
              .setStatusCode(500)
              .end();
        }
      });
}

在getAllArticlesHandler方法中,我们将一个事件传递给Vert事件总线,事件id为GET_ALL_ARTICLES。然后我们相应地处理成功和错误场景的回调

来自事件总线的消息将由ArticleRecipientVerticle使用,这将在后面演示

3.2 响应 Verticle

ArticleRecipientVerticle侦听传入的消息并注入一个Spring bean,它作为Spring和Vertx的集成点

我们将把Spring service bean注入到Verticle中,并调用相应的方法:

在新的Verticle中启动事件总线启动

@Override
public void start() throws Exception {
    super.start();
    vertx.eventBus().<String>consumer(GET_ALL_ARTICLES)
      .handler(getAllArticleService(articleService));
}

在这里articleService 是一个注入的Spring bean

@Autowired
private ArticleService articleService;

ArticleRecipientVerticle将继续监听地址GET_ALL_ARTICLES上的事件总线。一旦它接收到消息,它将其委托给getAllArticleService处理程序方法:

private Handler<Message<String>> getAllArticleService(ArticleService service) {
    return msg -> vertx.<String> executeBlocking(future -> {
        try {
            future.complete(
            mapper.writeValueAsString(service.getAllArticle()));
        } catch (JsonProcessingException e) {
            future.fail(e);
        }
    }, result -> {
        if (result.succeeded()) {
            msg.reply(result.result());
        } else {
            msg.reply(result.cause().toString());
        }
    });
}

4. Service Class

服务类是一个简单的实现,提供了与存储数据库层交互的方法:

@Service
public class ArticleService {
 
    @Autowired
    private ArticleRepository articleRepository;
 
    public List<Article> getAllArticle() {
        return articleRepository.findAll();
    }
}

ArticleRepository扩展了org.springframework.data.repository,并提供基本的CRUD功能

5. 部署Verticles

部署这个应用程序,就像我们对一个普通Spring Bean应用程序一样。我们首先创造一个Vertx实例,在完成Spring上下文初始化后,在其中部署verticles:

public class VertxSpringApplication {
 
    @Autowired
    private ServerVerticle serverVerticle;
 
    @Autowired
    private ArticleRecipientVerticle articleRecipientVerticle;
 
    public static void main(String[] args) {
        SpringApplication.run(VertxSpringApplication.class, args);
    }
 
    @PostConstruct
    public void deployVerticle() {
        Vertx vertx = Vertx.vertx();
        vertx.deployVerticle(serverVerticle);
        vertx.deployVerticle(articleRecipientVerticle);
    }
}

由于我们将ServerVerticle , ArticleRecipientVerticle 实例注入到Spring application类中。因此,我们需要对这两个类添加@Component注释

 @Component
 public class ServerVerticle extends AbstractVerticle {
     .......
 }

 @Component
 public class ArticleRecipientVerticle extends AbstractVerticle {
     .......
 }

让我们来测试这个应用程序:

@Test
public void givenUrl_whenReceivedArticles_thenSuccess() {
    ResponseEntity<String> responseEntity = restTemplate
      .getForEntity("http://localhost:8080/api/vertx/articles", String.class);
 
    assertEquals(200, responseEntity.getStatusCodeValue());
}

6. 结论

在本文中,我们了解了如何使用Spring和Vert.x构建RESTful web服务

上一篇:vert.x 初始


下一篇:SpringCloud+Vertx+Disruptor 金融业撮合交易系统实战