什么是FluentAPI?以jOOQ为例,一目了然ctx.select(BOOK.ID,BOOK.NAME).from(BOOK).where(BOOK.AUTHOR.eq(0)).fetch();FluentAPI的设计方式非常适合作为复杂对象的Builder。施工流程有序有序。流式调用也可用于构建DSL(领域特定语言)以解决特定领域的问题。更复杂的demo可以参考COLA中StateMachine和jOOQ的实现。案例:封装CompletableFuture首先我们来看一个使用CompletableFuture的案例。以下示例异步获取薪水和年龄。这个方法中使用了太多的trycatch,就像太多的ifelse一样,导致代码结构散乱,难以理解。@TestvoidtooMuchTryCatch(){CompletableFuturesalaryFuture=CompletableFuture.supplyAsync(()->1000);CompletableFutureageFuture=CompletableFuture.supplyAsync(()->30);整数工资=空;试试{salary=salaryFuture.get();}catch(Exceptione){thrownewRuntimeException(e);}assertEquals(工资,1000);整数年龄=空;尝试{age=ageFuture.get();}catch(Exceptione){thrownewRuntimeException(e);}assertEquals(年龄,30);这是我们项目中的一个场景:同时调用多个接口,如果接口异常则返回null或者一个catch-all值。如果项目中经常出现这样的调用模式,那么我们认为是特定领域的问题,应该考虑DSL的解决方案。为了避免在方法中使用过多的trycatch,我们可以使用CompletableFuture.exceptionally()。当异步调用出现错误时,我们往往只需要打印一条日志并返回一个默认值即可。因此,我们可以封装一个工具来规范Future的构建。然后开始表演。首先定义API,分为三个步骤:First、Second、Final。图表TD;First--"onFailure"-->Final;First--fallback-->Final;First--errMsg-->Second;Second--fallback-->Final;Final--run-->CompletableFuturepublicinterfaceAsync{}publicinterfaceAsyncContext{FirstStepasync(Suppliersupplier);}publicinterfaceFinalStepextendsAsync{CompletableFuturerun();}publicinterfaceFirstStepextendsFinalStep{SecondSteperrMsg(StringerrMsg);FinalStep后备(T后备);FinalSteponFailure(FunctiononFailure);}publicinterfaceSecondStepextendsFinalStep{FinalStepfallback(Tfallback);}然后具体实现:@Slf4jpublicclassAsyncImpl实现FirstStep,SecondStep{privateSupplier供应商;私人功能<可抛出,?扩展T>onFailure;私有字符串errMsg="异步执行异常";私人T回退;privatefinalExecutor执行者;publicAsyncImpl(Suppliersupplier,Executorexecutor){this.supplier=supplier;this.executor=执行者;}@OverridepublicSecondSteperrMsg(StringerrMsg){this.errMsg=errMsg;归还这个;}@OverridepublicFinalStepfallback(Tfallback){this.fallback=fallback;归还这个;}@OverridepublicFinalSteponFailure(FunctiononFailure){this.onFailure=onFailure;归还这个;}@OverridepublicCompletableFuturerun(){if(onFailure==null){onFailure=ex->{log.warn("{}",errMsg,ex);返回回退;};}CompletableFuturefuture=executor==null?CompletableFuture.supplyAsync(供应商):CompletableFuture.supplyAsync(供应商,执行者);返回future.exceptionally(onFailure);}}@Component@RequiredArgsConstructorpublicclassAsyncContextImplimplementsAsyncContext{privatefinalExecutorexecutor;@OverrideFirstpublicSuppliersupplier){returnnewAsyncImpl<>(supplier,executor);}}}最后,写一个单元测试这个单元测试介绍这个fluentapi的用法,不用多说。类AsyncContextTest{私有AsyncContextasyncCtx;@BeforeEachvoidsetup(){asyncCtx=newAsyncContextImpl(null);}privateIntegerfuckUpTask(){thrownewRuntimeException("FUCKUP");}@TestvoiddefaultFail(){CompletableFuturefuture=asyncCtx.async(this::fuckUpTask).run();assertNull(future.join());}@TestvoidonFailure(){CompletableFuturefuture=asyncCtx.async(this::fuckUpTask).onFailure(ex->-1).run();assertEquals(future.join(),-1);}@TestvoiderrMsg(){CompletableFuturefuture=asyncCtx.async(this::fuckUpTask).errMsg("FUCKUP").fallback(-1).run();assertEquals(future.join(),-1);}@TestvoidmultiTasks(){CompletableFuturefailFuture=asyncCtx.async(this::fuckUpTask).fallback(-1).run();CompletableFuturesuccessFuture=asyncCtx.async(()->1).run();assertEquals(failFuture.join(),-1);assertEquals(successFuture.join(),1);}}Kotlin版最近学习kotlin,所以写了一个kotlin版api.ktinterfaceAsyncinterfaceFinalStep:Async{funrun():CompletableFuture}interfaceFirstStep:Async,FinalStep{funonFailure(x:(Throwable)->T):FinalStepfunerrMsg(msg:String):SecondStepfunfallback(back:T):FinalStep}interfaceSecondStep:Async,FinalStep{funfallback(back:T):FinalStep}interfaceAsyncContext{funasync(x:()->T):FirstStep}impl.ktimportjava.util.concurrent.CompletableFutureimportjava.util.concurrent.ExecutorclassAsyncContextImpl(privatevalexecutor:Executor?=null):AsyncContext{overridefunasync(x:()->T):FirstStep{returnAsyncImpl(x,executor)}}classAsyncImpl(privatevalsupplier:()->T,privatevalexecutor:Executor?):FirstStep,SecondStep{privatevaronFailure:((Throwable)->T?)?=nullprivatevarerrMsg:String="FUCKUP"privatevarfallback:T?=nulloverridefunonFailure(x:(Throwable)->T):FinalStep{this.onFailure=xreturnthis}overridefunerrMsg(msg:String):SecondStep{this.errMsg=msg返回这个}overridefunfallback(back:T):FinalStep{this.fallback=backreturnthis}overridefunrun():CompletableFuture{if(onFailure==null)onFailure={ex:Throwable->log.warn("{}",errMsg,ex)fallback}returncreateFuture().exceptionally(onFailure)}privatefuncreateFuture():CompletableFuture{returnif(executor==null)CompletableFuture.supplyAsync(供应商)其他CompletableFuture.supplyAsync(供应商,执行者)}}