本教程将详细介绍 Spring WebFlux 的基本概念、核心组件以及如何使用它来构建响应式 Web 应用。我们将使用一个简单的 RESTful 服务作为示例,逐步演示 WebFlux 的功能。
什么是 Spring WebFlux?
Spring WebFlux 是 Spring Framework 5.0 引入的一个新的响应式 Web 框架。与传统的 Spring MVC 不同,WebFlux 采用了响应式编程模型,可以更好地应对高并发,低延迟的 Web 应用场景。
WebFlux 主要基于两个响应式库:Reactor 和 RxJava。在本教程中,我们将使用 Reactor 作为响应式库。
准备工作
首先,我们需要创建一个新的 Spring Boot 项目。使用 Spring Initializr(start.spring.io/ ↗)创建一个新项目,选择以下依赖:
- WebFlux
- Lombok(可选,用于简化实体类的编写)
创建并解压项目后,导入到你的 IDE 中。
开始构建 WebFlux 应用
1. 创建一个简单的实体类
我们将创建一个简单的 Person 实体类。为简化代码,我们使用 Lombok 的 @Data 注解。
import lombok.Data;
@Data
public class Person {
private Long id;
private String name;
private int age;
}
2. 创建一个人员数据存储
为了模拟从数据库获取数据的场景,我们创建一个 PersonRepository 接口,并提供一些简单的模拟数据。
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
public interface PersonRepository {
Flux<Person> findAll();
Mono<Person> findById(Long id);
}
接着,创建一个 PersonRepository 的实现类:PersonRepositoryImpl。
import org.springframework.stereotype.Repository;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.HashMap;
import java.util.Map;
@Repository
public class PersonRepositoryImpl implements PersonRepository {
private final Map<Long, Person> people = new HashMap<>();
public PersonRepositoryImpl() {
// 初始化模拟数据
people.put(1L, new Person(1L, "Alice", 30));
people.put(2L, new Person(2L, "Bob", 35));
people.put(3L, new Person(3L, "Charlie", 40));
}
@Override
public Flux<Person> findAll() {
return Flux.fromIterable(people.values());
}
@Override
public Mono<Person> findById(Long id) {
return Mono.justOrEmpty(people.get(id));
}
}
3. 创建 RESTful 路由和处理器
我们将使用函数式的方式创建 RESTful 路由和处理器。
首先,创建一个 PersonHandler 类,处理 HTTP 请求。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;
@Component
public class PersonHandler {
@Autowired
private PersonRepository personRepository;
public Mono<ServerResponse> getAllPeople(ServerRequest request) {
return ServerResponse.ok().body(personRepository.findAll(), Person.class);
}
public Mono<ServerResponse> getPersonById(ServerRequest request) {
Long personId = Long.valueOf(request.pathVariable("id"));
return personRepository.findById(personId)
.flatMap(person -> ServerResponse.ok().bodyValue(person))
.switchIfEmpty(ServerResponse.status(HttpStatus.NOT_FOUND).build());
}
}
然后,创建一个 PersonRouter 类,定义 RESTful 路由。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.web.reactive.function.server.RequestPredicates.*;
@Configuration
public class PersonRouter {
@Autowired
privatePersonHandler personHandler;
@Bean
public RouterFunction<ServerResponse> route() {
return RouterFunctions
.route(GET("/people").and(accept(APPLICATION_JSON)), personHandler::getAllPeople)
.andRoute(GET("/people/{id}").and(accept(APPLICATION_JSON)), personHandler::getPersonById);
}
}
4. 运行应用
现在,我们已经完成了一个简单的 WebFlux 应用的开发。运行项目的主类 DemoApplication,然后尝试访问以下 URL:
- 获取所有人员:http://localhost:8080/people ↗
- 根据 ID 获取人员:http://localhost:8080/people/1 ↗
你将看到 JSON 格式的返回结果。
总结
在本教程中,我们介绍了 Spring WebFlux 的基本概念和核心组件,并使用一个简单的 RESTful 服务作为示例。WebFlux 采用响应式编程模型,非常适合高并发、低延迟的场景。希望本教程能帮助你入门 Spring WebFlux,了解响应式编程的基本概念。
未来的教程中,我们将进一步探讨 WebFlux 的高级功能,如错误处理、过滤器、测试等。敬请期待!