Intégration Vert.x Spring

1. Vue d’ensemble

Dans cet article rapide, nous aborderons l’intégration de Spring avec Vert-x et tirerons parti du meilleur des deux mondes: la fonctionnalité Spring, puissante et bien connue, et la boucle à événement unique réactive de Vert.x.

Pour en savoir plus sur Vert.x, veuillez vous référer à notre lien d’introduction:/vertx[ici].

2. Installer

Premièrement, mettons en place nos dépendances:

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

Notez que nous avons exclu la dépendance intégrée Tomcat de _spring-boot-starter-web s _ puisque nous allons déployer nos services à l’aide de verticles.

Vous pouvez trouver les dernières dépendances here .

3. Application Spring Vert.x

Nous allons maintenant construire un exemple d’application avec deux verticules déployés.

Le premier Verticle achemine les demandes au gestionnaire qui les envoie sous forme de messages à l’adresse indiquée. L’autre Verticule écoute à une adresse donnée.

Voyons cela en action.

3.1. Expéditeur Verticule

  • ServerVerticle accepte les demandes HTTP et les envoie sous forme de messages à une adresse désignée. ** Créons une classe ServerVerticle étendant le AbstractVerticle, et substituons la méthode start () pour créer notre serveur HTTP:

@Override
public void start() throws Exception {
    super.start();

    Router router = Router.router(vertx);
    router.get("/api/baeldung/articles")
      .handler(this::getAllArticlesHandler);

    vertx.createHttpServer()
      .requestHandler(router::accept)
      .listen(config().getInteger("http.port", 8080));
}

Dans le gestionnaire de demandes du serveur, nous avons passé un objet router , qui redirige toute demande entrante vers le gestionnaire 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();
        }
      });
}

Dans la méthode du gestionnaire, nous transmettons un événement au bus d’événements Vert.x, avec un ID d’événement tel que GET ALL ARTICLES. Ensuite, nous traitons le rappel en conséquence pour les scénarios de réussite et d’erreur.

Le message du bus d’événements sera utilisé par le ArticleRecipientVerticle, décrit dans la section suivante.

3.2. Verticule du destinataire

  • ArticleRecipientVerticle écoute les messages entrants et injecte un bean Spring ** . C’est le point de rendez-vous de Spring et Vert.x.

Nous allons injecter le bean service Spring dans une verticale et invoquer les méthodes respectives:

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

Ici, articleService est un haricot printanier injecté:

@Autowired
private ArticleService articleService;

Ce Verticle continuera à écouter le bus d’événements sur une adresse GET ALL ARTICLES. Une fois qu’il aura reçu un message, il le déléguera à la méthode 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());
        }
    });
}

Ceci effectue l’opération de service requise et répond au message avec le statut. La réponse au message est référencée sur le ServerVerticle et le callback result comme nous l’avons vu dans la section précédente.

4. Classe de service

La classe de service est une implémentation simple, fournissant des méthodes pour interagir avec la couche de référentiel:

@Service
public class ArticleService {

    @Autowired
    private ArticleRepository articleRepository;

    public List<Article> getAllArticle() {
        return articleRepository.findAll();
    }
}

ArticleRepository étend, org.springframework.data.repository.CrudRepository et fournit les fonctionnalités de base de CRUD.

5. Déploiement de verticules

Nous déploierons l’application, comme nous le ferions pour une application Spring Boot normale. Nous devons créer une instance Vert.X et y déployer des verticules après l’initialisation du contexte Spring:

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);
    }
}

Notez que nous injectons des occurrences de verticule dans la classe d’application Spring. Donc, nous devrons annoter les classes de Verticle,

Nous devrons donc annoter les classes Verticle ServerVerticle et ArticleRecipientVerticle avec @Component.

Testons l’application:

@Test
public void givenUrl__whenReceivedArticles__thenSuccess() {
    ResponseEntity<String> responseEntity = restTemplate
      .getForEntity("http://localhost:8080/api/baeldung/articles", String.class);

    assertEquals(200, responseEntity.getStatusCodeValue());
}

6. Conclusion

Dans cet article, nous avons appris comment créer un service Web RESTful à l’aide de Spring et Vert.x.

Comme d’habitude, l’exemple est disponible over sur GitHub.