这里简单介绍下springboot整合webFlux(入门) ,使用netty通信。
首先是创建一个springboot项目,这里就不介绍怎么创建了。
接下来是导入依赖包:
<!--webflux--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency>
(使用这个依赖包后,不要再导入spring-boot-starter-web包了,因为我们webflux使用的是netty)
然后是创建一个简单的pojo:
User.java
package com.test.webflux.pojo; import lombok.Data; /** * @Author:JCccc * @Description: * @Date: created in 16:08 2019/5/30 */ @Data public class User { /** * id */ private Long id; /** * 姓名 */ private String name; /** * 描述 */ private String desc; }
接下来是dao层(netty不支持mysql,所以想要对数据进行CRUD可以采取整合mongodb和redis),这里我暂且采用的ConcurrentMap来操作数据:
UserRepository.java
package com.test.webflux.dao; import com.test.webflux.pojo.User; import org.springframework.stereotype.Repository; import java.util.Collection; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicLong; /** * @Author:JCccc * @Description: * @Date: created in 16:30 2019/5/30 */ @Repository public class UserRepository { private ConcurrentMap<Long,User> repository = new ConcurrentHashMap<>(); private static final AtomicLong idGenerator = new AtomicLong(0); public Long save(User user){ Long id=idGenerator.incrementAndGet(); user.setId(id); repository.put(id, user); return id; } public Collection<User> findAll() { return repository.values(); } public User findUserById(Long id) { return repository.get(id); } public Long updateUser(User user) { repository.put(user.getId(), user); return user.getId(); } public Long deleteUser(Long id) { repository.remove(id); return id; } }
接下来是handler层,这里简单列举了对ConcurrentMap进行CRUD的几个方法,
UserHandler.java
package com.test.webflux.handler; import com.test.webflux.dao.UserRepository; import com.test.webflux.pojo.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; /** * @Author:JCccc * @Description: * @Date: created in 16:38 2019/5/30 */ @Component public class UserHandler { private final UserRepository userRepository; @Autowired public UserHandler(UserRepository userRepository) { this.userRepository = userRepository; } public Mono<Long> save(User user) { return Mono.create(userMonoSink -> userMonoSink.success(userRepository.save(user))); } public Mono<User> findUserById(Long id) { return Mono.justOrEmpty(userRepository.findUserById(id)); } public Flux<User> findAllUser() { return Flux.fromIterable(userRepository.findAll()); } public Mono<Long> modifyUser(User user) { return Mono.create(userMonoSink -> userMonoSink.success(userRepository.updateUser(user))); } public Mono<Long> deleteUser(Long id) { return Mono.create(userMonoSink -> userMonoSink.success(userRepository.deleteUser(id))); } }
最后,创建下controller层写几个API(这里采用restful风格):
UserWebFluxController.java
package com.test.webflux.controller; import com.test.webflux.handler.UserHandler; import com.test.webflux.pojo.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; /** * @Author:JCccc * @Description: * @Date: created in 16:44 2019/5/30 */ @RestController @RequestMapping(value = "/user") public class UserWebFluxController { @Autowired private UserHandler userHandler; /** * 根据ID查询某个User * @param id * @return */ @GetMapping(value = "/{id}") public Mono<User> findUserById(@PathVariable("id") Long id) { return userHandler.findUserById(id); } /** * 查找所有User * @return */ @GetMapping() public Flux<User> findAllUser() { return userHandler.findAllUser(); } /** * 插入User * @param user * @return */ @PostMapping() public Mono<Long> saveUser(@RequestBody User user) { return userHandler.save(user); } /** * 修改User * @param user * @return */ @PutMapping() public Mono<Long> modifyUser(@RequestBody User user) { return userHandler.modifyUser(user); } /** * 根据ID删除User * @param id * @return */ @DeleteMapping(value = "/{id}") public Mono<Long> deleteUser(@PathVariable("id") Long id) { return userHandler.deleteUser(id); } }
到此,简单的webflux入门整合已经完成了。
那么我们最后把项目跑起来,简单测试一下,
接下来使用postman调用下插入user接口 :
再调一下查询接口:
OK,其余的接口也是一样调用,那么简单的介绍就此完毕了。
(PS:想了解更多的,可以去查下mono和flux的相关资料,可以往上翻下,controller里面用到了Mono)
Mono 和 Flux 适用于两个场景,即: Mono:实现发布者,并返回 0 或 1 个元素,即单对象。 Flux:实现发布者,并返回 N 个元素,即 List 列表对象。 有人会问,这为啥不直接返回对象,比如返回 City/Long/List。 原因是,直接使用 Flux 和 Mono 是非阻塞写法,相当于回调方式。 利用函数式可以减少了回调,因此会看不到相关接口。这恰恰是 WebFlux 的好处:集合了非阻塞 + 异步