## 1 WebFlux基于注解的编程的实现
### 创建WebFlux项目
1. 创建Springboot项目,引入webflux的依赖
```xml
pom.xml
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.2.1.RELEASE
com.example
shangguigu09
0.0.1-SNAPSHOT
shangguigu09
shangguigu09
1.8
org.springframework.boot
spring-boot-starter-webflux
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
```
2. 在配置文件中,设置启动端口号8081
```yaml
server.port =8081
```
3. 从上到下设计代码:创建接口和实现类
```java
@Service
public class UserServiceImpl implements UserService {
private final Map users = new HashMap<>();
public UserServiceImpl() {
this.users.put(1,new User("lucy","nan",10));
this.users.put(2,new User("mary","nv",38));
this.users.put(3,new User("jack","nv",32));
}
@Override
public Mono getUserById(int id) {
return Mono.justOrEmpty(this.users.get(id));
}
@Override
public Flux getAllUser() {
return Flux.fromIterable(this.users.values());
}
@Override
public Mono savaUserInfo(Mono userMono) {
return userMono.doOnNext(person->{
int id = users.size() + 1;
users.put(id,person);
}).thenEmpty(Mono.empty());
}
}
```
4. 从下到上实现代码:实现业务逻辑
```java
@RestController
public class UserController {
@Autowired
private UserService userService;
//id
@GetMapping("/user/{id}")
public Mono getUserById(@PathVariable int id){
return userService.getUserById(id);
}
//all
@GetMapping("/user")
public Flux getAllUser(){
return userService.getAllUser();
}
//tianjian
@GetMapping("/saveuser")
public Mono saveUser(@RequestBody User user){
Mono userMono = Mono.just(user);
return userService.savaUserInfo(userMono);
}
@GetMapping("/hello/{latency}")
public Mono hello(@PathVariable long latency) {
System.out.println("Start:" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")));
System.out.println("Page count:" + COUNT.incrementAndGet());
Mono res = Mono.just("welcome to Spring Webflux").delayElement(Duration.ofSeconds(latency));//阻塞latency秒,模拟处理耗时
System.out.println("End: " + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")));
return res;
}
}
```
### 实现说明
* SpringMVC范式,同步阻塞方式,基于SpringMVC+Servlet+Tomcat
* SpringWebflux方式,异步非阻塞方式,基于SpringMVCWebflux+Reactor+Netty
## 2 WebFlux基于函数的编程的实现
### 简要说明
> bio,nio,aio
在使用函数式编程,需要自己初始化服务器
基于函数式编程模型的时候,有两个核心接口。
* RouterFunction 实现路由功能,请求转发给对应的handler
* HandlerFunction 处理请求生成响应函数。
核心任务定义两个函数式接口的实现,并启动需要的服务器。
SpringWebFlux的请求和响应是
* ServerRequest
* ServerResponse
### 实现流程
1. 从上到下实现业务bean
2. 创建handler实现Mono方法
```java
public class UserHandler {
private final UserService userService;
public UserHandler(UserService userService){
this.userService = userService;
}
//根据id
public Mono getUserById(ServerRequest request){
//获取id值
int userid = Integer.valueOf( request.pathVariable("id"));
Mono notFound = ServerResponse.notFound().build();
//调用service方法取得数据
Mono userMono = this.userService.getUserById(userid);
//UserMono进行转换返回。Reactor操作符
return userMono.flatMap(person->ServerResponse.ok().contentType(MediaType.APPLICATION_JSON)
.body(fromObject(person)))
.switchIfEmpty(notFound);
}
//所有用户
public Mono getAllUsers(){
Flux users = this.userService.getAllUser();
return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(users,User.class);
}
//添加
public Mono saveUser(ServerRequest request){
Mono userMono = request.bodyToMono(User.class);
return ServerResponse.ok().build(this.userService.savaUserInfo(userMono));
}
}
```
3. 创建并初始化服务器,设置路由和handler
```java
public class Server {
//创建路由
public RouterFunction route(){
UserService userService = new UserServiceImpl();
UserHandler handler = new UserHandler(userService);
return RouterFunctions.route(GET("/users/{id}").and(accept(MediaType.APPLICATION_JSON)),handler::getUserById);
// .andRoute(GET("users").and(accept(MediaType.APPLICATION_JSON)),handler::getAllUsers)
// .andRoute(GET("saveuser").and(accept(MediaType.APPLICATION_JSON)),handler::saveUser);
}
public void createReactorServer(){
RouterFunction route = route();
HttpHandler httpHandler = toHttpHandler(route);
ReactorHttpHandlerAdapter reactorHttpHandlerAdapter = new ReactorHttpHandlerAdapter(httpHandler);
HttpServer httpServer = HttpServer.create();
httpServer.handle(reactorHttpHandlerAdapter).bindNow();
}
public static void main(String[] args) throws Exception{
Server server = new Server();
server.createReactorServer();
System.out.println("enter to exit");
System.in.read();
}
}
```
## 3 WebClient调用
```java
public class Client {
public static void main(String[] args) {
WebClient webClient = WebClient.create("http://127.0.0.1:62418");
User userMono = webClient.get().uri("/users/{id}", "1").accept(MediaType.APPLICATION_JSON).retrieve().bodyToMono(User.class).block();
System.out.println(userMono.getName());
}
}
```