Vert.x Spring Integration

1. Обзор

В этой быстрой статье мы обсудим интеграцию Spring с Vert-x и используем лучшее из обоих миров: мощную и хорошо известную функцию Spring и реактивный цикл с одним событием из Vert.x.

Чтобы узнать больше о Vert.x, пожалуйста, обратитесь к нашей ссылке на вступительную статью:/vertx[здесь].

2. Настроить

Во-первых, давайте установим наши зависимости:

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

Обратите внимание, что мы исключили встроенную зависимость Tomcat из _spring-boot-starter-web s _ , поскольку мы собираемся развернуть наши сервисы с использованием вершин.

Вы можете найти последние зависимости here .

3. Приложение Spring Vert.x

Теперь мы создадим пример приложения с двумя развернутыми вершинами.

Первый Vertical направляет запросы обработчику, который отправляет их в виде сообщений на заданный адрес. Другая Вертикаль слушает по заданному адресу.

Давайте посмотрим на них в действии.

3.1. Отправитель Вертикаль

  • ServerVerticle принимает HTTP-запросы и отправляет их в виде сообщений на указанный адрес. ** Давайте создадим класс ServerVerticle , расширяющий AbstractVerticle, и переопределим метод start () , чтобы создать наш 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));
}

В обработчике запросов сервера мы передали объект router , который перенаправляет любой входящий запрос обработчику 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();
        }
      });
}

В методе-обработчике мы передаем событие в шину событий Vert.x с идентификатором события GET ALL ARTICLES. Затем мы обрабатываем обратный вызов соответственно для сценариев успеха и ошибок.

Сообщение от шины событий будет использовано ArticleRecipientVerticle, обсуждается в следующем разделе.

3.2. Получатель Вертикаль

  • ArticleRecipientVerticle прослушивает входящие сообщения и внедряет Spring bean ** . Он действует как место встречи для Spring и Vert.x.

Мы добавим служебный бин Spring в Verticle и вызовем соответствующие методы:

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

Здесь articleService является внедренным компонентом Spring:

@Autowired
private ArticleService articleService;

Эта статья будет продолжать прослушивать шину событий по адресу 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());
        }
    });
}

Это выполняет требуемую сервисную операцию и отвечает на сообщение со статусом. Ответ на сообщение ссылается на ServerVerticle и обратный вызов result , как мы видели в предыдущем разделе.

4. Класс обслуживания

Класс обслуживания - это простая реализация, предоставляющая методы для взаимодействия со слоем хранилища:

@Service
public class ArticleService {

    @Autowired
    private ArticleRepository articleRepository;

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

ArticleRepository расширяет, org.springframework.data.repository.CrudRepository и обеспечивает основные функции CRUD.

5. Развертывание статей

Мы будем развертывать приложение точно так же, как и в случае обычного приложения Spring Boot. Мы должны создать экземпляр Vert.X и развернуть в нем вертикали после завершения инициализации контекста 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);
    }
}

Обратите внимание, что мы внедряем экземпляры вертикулов в класс приложения Spring. Итак, нам придется аннотировать классы Verticle,

Таким образом, нам придется аннотировать вертикальные классы ServerVerticle и ArticleRecipientVerticle с помощью @Component.

Давайте протестируем приложение:

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

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

6. Заключение

В этой статье мы узнали о том, как создать RESTful WebService с использованием Spring и Vert.x.

Как обычно, пример доступен over on GitHub.