提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
Spring5中重要的变化是把响应式编程的思想应用到了框架的各个方面如Spring WebFlux, Spring Data和Spring Cloud Gateway。Spring5 的响应式编程默认以Reactor库为基础。Reactor内部提供了Flux和Mono两个代表异步数据系列的核心组件,它使开发人员能够方便快捷的构建异步非阻塞的应用程序。响应式编程应用场景很多,本文结合其异步非阻塞的特点列出以下应用场景:
适用于发送手机短信、发送邮件、图片上传等耗时较长的场景。
示例代码:
Mono.just(params).publishOn(Schedulers.elastic())
.flatMap(v -> doStep1(v))
.map(v -> doStep2(v))
.flatMap(v -> doStep3(v));
在前后端分离的开发模式中,有时前端需要的接口后端只是提供了多个功能单一的接口,前端需要挨个调用,然后把返回的结果进行合并,处理起来比较麻烦,这时后端可以通过API组合的方式对前端提供服务。
需求:根据订单号获取订单信息及对应的物流信息
如果查询订单信息和物流信息的服务都在一个项目中,可以通过异步并行查询方式提高性能。
项目仅需要引入Reactor、RxJava等异步框架即可
示例代码如下:
@Service
public class OrderService {
public String getOrderInfo(String orderId) {
try {
TimeUnit.SECONDS.sleep(50);
} catch (InterruptedException e) {
return "Error during thread sleep";
}
return orderId+"订单信息: 烟台苹果10斤";
}
}
@Service
public class LogisticsService {
public String getLogisticsInfo(String orderId) {
try {
TimeUnit.SECONDS.sleep(50);
} catch (InterruptedException e) {
return "Error during thread sleep";
}
return orderId +"物流信息: 烟台->潍坊中转->济南";
}
}
class DemojarApplicationTests {
@Autowired
private OrderService orderService;
@Autowired
private LogisticsService logisticsService;
void parrallelService() {
String orderId="DJ0001";
long start=System.currentTimeMillis();
//异步查询
Mono<String> orderInfo =Mono.just(orderId).publishOn(Schedulers.elastic())
.map(s->this.orderService.getOrderInfo(s));
Mono<String> logisticsInfo =Mono.just(orderId).publishOn(Schedulers.elastic())
.map(s->{return this.logisticsService.getLogisticsInfo(s);});
//合并查询结果
String orderLogisticsInfo = Mono.zip(orderInfo,logisticsInfo,(a,b)->{
//合并结果生成订单物流信息
return a+"\n "+b;
}).block();
long end=System.currentTimeMillis();
System.out.println("耗时"+(end -start)/1000+"s");
System.out.println("result\n "+orderLogisticsInfo);
}
利用Webflux中的WebClient实现异步rest服务调用,示例代码如下:
WebClient client = WebClient.create();
String orderId="JD0001";
Mono<String> orderInfo = client.get().uri("http://localhost:8080/order/{id}",orderId).retrieve().bodyToMono(String.class);
Mono<String> logisticsInfo = client.get().uri("http://localhost:8080/logistics/{id}",orderId).retrieve().bodyToMono(String.class);
String orderLogisticsInfo = Mono.zip(orderInfo,logisticsInfo,(a,b)->{
return a+" "+b;
}).block();
可利用Spring Cloud Gateway做为网关并进行API组合
WebFlux + R2DBC +spring cloud gateway,如果需要用到消息队列可引入 reactive spring cloud stream。