1. 概述
本文将探讨Vert.x与Spring的集成方案,结合两者优势:Spring强大的生态体系和Vert.x高效的单线程事件循环模型。关于Vert.x的基础知识,可参考我们的入门教程。
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.9.15</version>
</dependency>
⚠️ 注意:排除了Tomcat依赖,因为我们使用Verticle部署服务。最新版本可在Maven仓库查看。
3. Spring Vert.x应用实现
我们将构建包含两个Verticle的示例应用:
- 发送者Verticle:路由HTTP请求并转发为消息
- 接收者Verticle:监听指定地址处理消息
3.1. 发送者Verticle
ServerVerticle
接收HTTP请求并转发为消息。创建继承AbstractVerticle
的类:
@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));
}
请求处理逻辑:
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();
}
});
}
核心流程:
- 通过Event Bus发送消息(事件ID:
GET_ALL_ARTICLES
) - 处理成功/失败回调
- 消息由
ArticleRecipientVerticle
消费(下节详述)
3.2. 接收者Verticle
ArticleRecipientVerticle
监听消息并注入Spring Bean,作为Spring与Vert.x的桥梁:
@Override
public void start() throws Exception {
super.start();
vertx.eventBus().<String>consumer(GET_ALL_ARTICLES)
.handler(getAllArticleService(articleService));
}
注入的Spring Bean:
@Autowired
private ArticleService articleService;
消息处理逻辑:
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());
}
});
}
执行流程:
- 监听
GET_ALL_ARTICLES
地址 - 调用Spring服务处理业务
- 返回结果给发送者Verticle
4. 服务层实现
标准Spring Service实现,调用Repository层:
@Service
public class ArticleService {
@Autowired
private ArticleRepository articleRepository;
public List<Article> getAllArticle() {
return articleRepository.findAll();
}
}
ArticleRepository
继承CrudRepository
,提供基础CRUD功能。
5. Verticle部署
采用常规Spring Boot启动方式,在Spring上下文初始化后部署Verticle:
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);
}
}
✅ 关键点:
- Verticle类需标注
@Component
注解 - 通过
@PostConstruct
确保Spring注入完成后再部署
测试用例:
@Test
public void givenUrl_whenReceivedArticles_thenSuccess() {
ResponseEntity<String> responseEntity = restTemplate
.getForEntity("http://localhost:8080/api/baeldung/articles", String.class);
assertEquals(200, responseEntity.getStatusCodeValue());
}
6. 总结
本文展示了如何结合Spring和Vert.x构建REST服务,核心优势包括:
- Spring生态的成熟组件管理
- Vert.x的高性能事件循环模型
- 通过Event Bus实现解耦通信
完整示例代码见GitHub仓库。