Spring中新功能之WebFlux操作
1 说明
响应式编程操作中,Reactor 是满足 Reactive 规范框架
Reactor 有两个核心类,Mono 和 Flux,这两个类实现接口 Publisher,提供丰富操作符。Flux 对象实现发布者,返回 N 个元素;Mono 实现发布者,返回 0 或者 1 个元素.
Flux 和 Mono 都是数据流的发布者,使用 Flux 和 Mono 都可以发出三种数据信号: 元素值,错误信号,完成信号,错误信号和完成信号都代表终止信号,终止信号用于告诉订阅者数据流结束了,错误信号终止数据流同时把错误信息传递给订阅者.
2 操作案例
1 引入依赖
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-core</artifactId>
<version>3.1.5.RELEASE</version>
</dependency>
2 测试类
public class Test{
public static void main(String[] args) {
// just 方法直接声明
Flux.just(1,2,3,4);
Mono.just(1);
// 其他的方法
Integer[] array = {1,2,3,4};
Flux.fromArray(array);
List<Integer> list = Arrays.asList(array);
Flux.fromIterable(list);
Stream<Integer> stream = list.stream();
Flux.fromStream(stream);
}
}
信号特点:
- 错误信号和完成信号都是终止信号,不能共存的
- 如果没有发送任何元素值,而是直接发送错误或者完成信号,表示是空数据流
- 如果没有错误信号,没有完成信号,表示是无限数据流
调用 just 或者其他方法只是声明数据流,数据流并没有发出,只有进行订阅之后才会触 发数据流,不订阅什么都不会发生的.
列如
// just 方法直接声明
Flux.just(1,2,3,4).subscribe(System.out::print);
Mono.just(1).subscribe(System.out::print);
3 SpringWebflux 执行流程
1 SpringWebflux 基于 Reactor,默认使用容器是 Netty,Netty 是高性能的 NIO 框架,异步非阻塞的框架.
2 SpringWebflux 执行过程和 SpringMVC 相似的. SpringWebflux 核心控制器 DispatchHandler,实现接口 WebHandler.
3 SpringWebflux 里面 DispatcherHandler,负责请求的处理
- SpringWebflux 里面 DispatcherHandler,负责请求的处理
- HandlerAdapter:真正负责请求处理
- HandlerResultHandler:响应结果处理
4 SpringWebflux 实现函数式编程,由两个接口:
- RouterFunction(路由处理)
- HandlerFunction(处理函数)
4 基于注解编程
1 创建Spring Boot 工程,引入 Webflux 依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
2 创建实体类
public class User{
private String name;
private String gender;
private Integer age;
// 省略 构造 setter/getter
}
创建接口
public interface UserService{
// 根据id查询
Mono<User> getUserById(int id);
// 查询所有用户
Flux<User> getAllUser();
// 添加用户
Mono<Void> saveUserInfo(Mono<User> user);
}
实现类
public class UserServiceImpl implements UserService {
// 创建 map 集合存储数据
private final Map<Integer,User> users = new HashMap<>();
public UserServiceImpl() {
this.users.put(1,new User("lacy","男",20));
this.users.put(2,new User("may","女",30));
this.users.put(3,new User("jack","男",50));
}
// 根据 id 查询
@Override
public Mono<User> getUserById(int id) {
return Mono.justOrEmpty(this.users.get(id));
}
// 查询多个用户
@Override
public Flux<User> getAllUser() {
return Flux.fromIterable(this.users.values());
}
// 添加用户
@Override
public Mono<Void> saveUserInfo(Mono<User> userMono) {
return userMono.doOnNext(person -> {
// 向 map 集合里面放值
int id = users.size()+1;
users.put(id,person);
}).thenEmpty(Mono.empty());
}
}
控制器
@RestController
public class UserController {
// 注入 service
@Autowired
private UserService userService;
// id 查询
@GetMapping("/user/{id}")
public Mono<User> geetUserId(@PathVariable int id) {
return userService.getUserById(id);
}
// 查询所有
@GetMapping("/user")
public Flux<User> getUsers() {
return userService.getAllUser();
}
// 添加
@PostMapping("/saveuser")
public Mono<Void> saveUser(@RequestBody User user) {
Mono<User> userMono = Mono.just(user);
return userService.saveUserInfo(userMono);
}
}
SpringMVC 方式实现,同步阻塞的方式,基于 SpringMVC+Servlet+Tomcat
SpringWebflux 方式实现,异步非阻塞 方式,基于 SpringWebflux+Reactor+Netty