這篇文章承接上篇文章,沒有看過的小伙伴可以先去看上篇SpringFlux入門(上篇),涉及到的兩個重要的對象,F(xiàn)lux和Mono來看下官網(wǎng)是怎么介紹的
Reactor is the reactive library of choice for Spring WebFlux. It provides the Mono and Flux API types to work on data sequences of 0..1 and 0..N
中文意思:
Reactor是Spring WebFlux的首選反應(yīng)式編程庫。 它提供Mono和Flux API類型來處理0..1和0..N的數(shù)據(jù)序列
文章末尾會附上官網(wǎng)鏈接地址
Mono

Mono 是表示包含 0 或者 1 個元素的異步序列
創(chuàng)建Mono有兩種方法
- 通過Mono靜態(tài)方法創(chuàng)建:
empty():創(chuàng)建一個不包含任何元素,只發(fā)布結(jié)束消息的序列。
just():可以指定序列中包含的全部元素。創(chuàng)建出來的 Mono序列在發(fā)布這些元素之后會自動結(jié)束
justOrEmpty():從一個 Optional 對象或可能為 null 的對象中創(chuàng)建 Mono。只有 Optional 對象中包含值或?qū)ο蟛粸?null 時,Mono 序列才產(chǎn)生對應(yīng)的元素。
error(Throwable error):創(chuàng)建一個只包含錯誤消息的序列。
never():創(chuàng)建一個不包含任何消息通知的序列。
ps:
Mono.justOrEmpty(userDao.findById(id));
- 通過 create()方法來使用 MonoSink 來創(chuàng)建 Mono。
ps:
Mono.create(userMonoSink -> userMonoSink.success(userDao.save(user)));
Flux
Flux 是表示包含 0 到 N 個元素的異步序列

有個大概的認(rèn)識就差不多了,先上代碼
這里照例使用的是模擬的數(shù)據(jù),不連接數(shù)據(jù)庫,以免增加上手難度
- 工具類
package com.tanoak.utils;
import com.google.common.collect.Lists;
import com.tanoak.pojo.User;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author tanoak@qq.com
* @Desc 模擬數(shù)據(jù)類
*/
public class DataUtils {
public static List<User> users =new ArrayList<>() ;;
public static Map<Long,User> userMap =new HashMap<>();
static {
User user1 = new User(1L,"張三") ;
User user2 = new User(2L,"李四") ;
User user3 = new User(3L,"王五") ;
users.add(user1);
users.add(user2) ;
users.add(user3) ;
userMap.put(1L,user1) ;
userMap.put(2L,user2) ;
userMap.put(3L,user3) ;
}
public static List<User> listUser(){
return users ;
}
public static User findById(Long id){
return userMap.get(id) ;
}
}
-
pojo層
package com.tanoak.pojo;
import lombok.Data;
/**
@author tanoak@qq.com
-
@Desc
*/
//@Data
public class User {
private Long id ;
private String name ;public User() {
}public User(Long id, String name) {
this.id = id;
this.name = name;
}public Long getId() {
return id;
}public void setId(Long id) {
this.id = id;
}public String getName() {
return name;
}public void setName(String name) {
this.name = name;
}@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + ''' +
'}';
}
}
Lombok在IDEA 18.1版本中會有失效的情況,在這里請教下解決方案
-
Dao層
package com.tanoak.demo1.dao; import com.tanoak.pojo.User; import com.tanoak.utils.DataUtils; import org.springframework.stereotype.Component; import java.util.List; /** * @author tanoak@qq.com * @Desc */ @Component public class UserDao { public Integer save(User user){ if(null==user){ return 0 ; } System.out.println("保存成功"); return 1 ; } public Integer del(Long id){ if(null!=id){ System.out.println("刪除成功"); return 1 ; } return 0 ; } public Integer update(User user){ if(null==user){ return 0 ; } System.out.println("修改成功"); return 1 ; } public List<User> findAll(){ return DataUtils.listUser() ; } public User findById(Long id){ return DataUtils.findById(id); } } -
handle層
package com.tanoak.demo1.handler; import com.tanoak.demo1.dao.UserDao; import com.tanoak.pojo.User; import org.springframework.stereotype.Component; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import javax.annotation.Resource; /** * @author 656443534@qq.com * @Desc 增刪查改 可以把它當(dāng)成Service層 */ @Component public class UserHandler { @Resource private UserDao userDao; public Mono<Integer> save(User user) { return Mono.create(userMonoSink -> userMonoSink.success(userDao.save(user))); } public Mono<Integer> del(Long id) { return Mono.create(userMonoSink -> userMonoSink.success(userDao.del(id))); } public Mono<User> findById(Long id) { return Mono.just(userDao.findById(id)); } public Flux<User> findAll() { return Flux.fromIterable(userDao.findAll()); } public Mono<Integer> update(User user) { return Mono.create(userMonoSink -> userMonoSink.success(userDao.update(user))); } } -
Controller層
package com.tanoak.demo1.controller; import com.tanoak.demo1.handler.UserHandler; import com.tanoak.pojo.User; import org.springframework.web.bind.annotation.*; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import javax.annotation.Resource; /** * @author 656443534@qq.com * @date 2018/5/20 15:51 * @Desc REST風(fēng)格 */ @RestController @RequestMapping("/user") public class UserController { @Resource private UserHandler userHandler ; @PostMapping() public Mono<Integer> save(@RequestBody User user) { return userHandler.save(user) ; } @GetMapping("{id}") public Mono<User> query(@PathVariable("id")Long id) { return userHandler.findById(id) ; } @GetMapping() public Flux<User> queryAll() { return userHandler.findAll() ; } @DeleteMapping("{id}") public Mono<Integer> del(@PathVariable("id")Long id) { return userHandler.del(id) ; } @PutMapping() public Mono<Integer> update(@RequestBody User user) { return userHandler.update(user) ; } }
使用PostMan進(jìn)行測試,這里截取發(fā)送POST請求與DELETE請求


至此一個簡單的CRUD項(xiàng)目就完成了,在這里不涉及到數(shù)據(jù)庫,DataUtils充當(dāng)了數(shù)據(jù)庫,在實(shí)際應(yīng)用中個人感覺距離生產(chǎn)環(huán)境還有一段路要走,但是github上已經(jīng)有關(guān)于異步j(luò)dbc的解決方案,等后面我研究后再分享出來吧!
異步JDBC項(xiàng)目地址:https://github.com/mauricio/postgresql-async
異步j(luò)dbc與同步性能對比
官網(wǎng)資料:
WebFlux官網(wǎng)資料
Flux官網(wǎng)資料
Mono官網(wǎng)資料
參考博客:
泥瓦匠BYSocket