最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java如何利用CompletableFuture描述任務之間的關系

 更新時間:2023年07月30日 08:30:43   作者:Shawn_Shawn  
Java如何根據線程的執(zhí)行結果執(zhí)行下一步動作呢,Future的另一個實現類CompletableFuture能夠優(yōu)雅的解決異步化問題,下面就跟隨小編一起了解一下吧

java線程-如何獲取到線程執(zhí)行的結果一文中講解了Future的用法和實現原理,Future主要用于獲取線程執(zhí)行的結果,那么如何根據線程的執(zhí)行結果執(zhí)行下一步動作呢?Future的另一個實現類CompletableFuture能夠優(yōu)雅的解決異步化問題。

CompletableFuture

CompletableFuture是java8新增的,這個類實現了兩個接口,一個是Future接口,一個是CompletionStage接口。

CompletableFuture提供了非常強大的Future的擴展功能,可以幫助我們簡化異步編程的復雜性,提供了函數式編程的能力,可以通過回調的方式處理計算結果,并且提供了轉換和組合CompletableFuture的方法。

CompletableFuture被設計在Java中進行異步編程。異步編程意味著在主線程之外創(chuàng)建一個獨立的線程,與主線程分隔開,并在上面運行一個非阻塞的任務,然后通知主線程進展,成功或者失敗。

通過這種方式,你的主線程不用為了任務的完成而阻塞/等待,你可以用主線程去并行執(zhí)行其他的任務。 使用這種并行方式,極大地提升了程序的表現。

CompletionStage

CompletionStage是java8新增的接口,用于異步執(zhí)行中的階段處理。CompletionStage定義了一組接口用于在一個階段執(zhí)行結束之后,要么繼續(xù)執(zhí)行下一個階段,要么對結果進行轉換產生新的結果等等,一般來說要執(zhí)行下一個階段都需要上一個階段正常完成,當然這個類也提供了對異常結果的處理接口。

任務與任務之間是有聯系關系的,比如串行關系,并行關系,AND,OR等關系。

描述串行關系

CompletionStage接口里面描述串行關系,主要是thenApply、thenAccept、thenRunthenCompose這四個系列的接口。

public <U> CompletionStage<U> thenApply(Function<? super T,? extends U> fn);
public <U> CompletionStage<U> thenApplyAsync(Function<? super T,? extends U> fn);
public <U> CompletionStage<U> thenApplyAsync(Function<? super T,? extends U> fn, 
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Executor executor);
public CompletionStage<Void> thenAccept(Consumer<? super T> action);
public CompletionStage<Void> thenAcceptAsync(Consumer<? super T> action);
public CompletionStage<Void> thenAcceptAsync(Consumer<? super T> action, 
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Executor executor);
public CompletionStage<Void> thenRun(Runnable action);
public CompletionStage<Void> thenRunAsync(Runnable action);
public CompletionStage<Void> thenRunAsync(Runnable action, 
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Executor executor);
public <U> CompletionStage<U> thenCompose(Function<? super T, ? extends CompletionStage<U>> fn);
public <U> CompletionStage<U> thenComposeAsync(Function<? super T, ? extends CompletionStage<U>> fn);
public <U> CompletionStage<U> thenComposeAsync(Function<? super T, ? extends CompletionStage<U>> fn,
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Executor executor);
  • thenApply系列方法,入參類型是接口 Function<T, R>,這個接口里與CompletionStage相關的方法是 R apply(T t),這個方法既能接收參數也支持返回值,所以 thenApply 系列方法返回的是CompletionStage<R>。
  • thenAccept系列方法,入參類型是接口Consumer<T>,這個接口里與CompletionStage相關的方法是void accept(T t),這個方法雖然支持參數,但卻不支持回值,所以thenAccept系列方法返回的是CompletionStage<Void>。
  • thenRun系列方法,入參類型是接口Runnable,Runnable既不能接收參數也不支持返回值,所以thenRun系列方法返回的是CompletionStage<Void>。
  • thenCompose系列方法,這個系列的方法會新創(chuàng)建出一個子流程,最終結果和thenApply系列是相同的。
  • 這些方法里面Async代表的是異步執(zhí)行fn、consumer或者action。
// 描述串行關系
// 期待輸出
// hello world
// Hello CompletableFuture
private static void serial() throws Exception {
 ?CompletableFuture<Void> t1 =
 ? ?CompletableFuture.supplyAsync(() -> "Hello")
 ?  .thenApply(s -> s + " World")
 ?  .thenApply(String::toLowerCase)
 ?  .thenAccept(System.out::println);

 ?CompletableFuture<Void> t2 =
 ? ?CompletableFuture.supplyAsync(() -> "Hello")
 ?  .thenCompose(s -> CompletableFuture.supplyAsync(() -> s + " CompuletableFuture"))
 ?  .thenAccept(System.out::println);

 ?t1.thenRun(() -> t2.join());
 ?t1.join();
}

描述AND聚合關系

CompletionStage接口里面描述AND聚合關系,主要是thenCombine、thenAcceptBoth、runAfterBoth這三個系列的接口。

public <U,V> CompletionStage<V> thenCombine (CompletionStage<? extends U> other, 
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? BiFunction<? super T,? super U,? extends V> fn);
public <U,V> CompletionStage<V> thenCombineAsync(CompletionStage<? extends U> other,
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? BiFunction<? super T,? super U,? extends V> fn);
public <U,V> CompletionStage<V> thenCombineAsync(CompletionStage<? extends U> other,
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? BiFunction<? super T,? super U,? extends V> fn,
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Executor executor);
public <U> CompletionStage<Void> thenAcceptBoth(CompletionStage<? extends U> other, 
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?BiConsumer<? super T, ? super U> action);
public <U> CompletionStage<Void> thenAcceptBothAsync(CompletionStage<? extends U> other,
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? BiConsumer<? super T, ? super U> action);
public <U> CompletionStage<Void> thenAcceptBothAsync(CompletionStage<? extends U> other,
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? BiConsumer<? super T, ? super U> action,
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Executor executor);
public CompletionStage<Void> runAfterBoth(CompletionStage<?> other,
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Runnable action);
public CompletionStage<Void> runAfterBothAsync(CompletionStage<?> other,
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Runnable action);
  • thenAcceptBoth系列方法,入參包括CompletionStage以及BiConsumer<T,U>,這一組函數是用來接受兩個CompletableFuture的返回值,并將其組合到一起。
  • thenCombine系列方法,與thenAcceotBoth類似,與thenAcceptBoth不同的是,thenCombine將兩個任務結果合并后會返回一個全新的值作為出參。
  • runAfterBoth系列方法,入參類型為CompletionStage<?>Runnable
/*
hello world
Hello CompuletableFuture
thenCombine end
thenAcceptBoth end
runAfterBoth end
*/
private static void and() throws Exception {
 ?CompletableFuture<Void> t1 =
 ? ? ?CompletableFuture.supplyAsync(() -> "Hello")
 ? ? ? ?  .thenApply(s -> s + " World")
 ? ? ? ?  .thenApply(String::toLowerCase)
 ? ? ? ?  .thenAccept(System.out::println);

 ?CompletableFuture<Void> t2 =
 ? ? ?CompletableFuture.supplyAsync(() -> "Hello")
 ? ? ? ?  .thenCompose(s -> CompletableFuture.supplyAsync(() -> s + " CompuletableFuture"))
 ? ? ? ?  .thenAccept(System.out::println);

 ?CompletableFuture<String> t3 = t1.thenCombine(t2, (__, s) -> "end");
 ?t3.thenAccept(s -> System.out.println("thenCombine " + s));
 ?t3.join();

 ?CompletableFuture<Void> t4 =
 ? ? ?t1.thenAcceptBoth(t2, (__, s) -> System.out.println("thenAcceptBoth end"));
 ?t4.join();

 ?CompletableFuture<Void> t5 = t1.runAfterBoth(t2, () -> System.out.println("runAfterBoth end"));
 ?t5.join();
}

描述OR聚合關系

CompletionStage接口里面描述OR聚合關系,主要是applyToEither、acceptEitherrunAfterEither系列的接口。

public <U> CompletionStage<U> applyToEither(CompletionStage<? extends T> other,
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Function<? super T, U> fn);
public <U> CompletionStage<U> applyToEitherAsync(CompletionStage<? extends T> other,
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Function<? super T, U> fn);

public <U> CompletionStage<U> applyToEitherAsync(CompletionStage<? extends T> other,
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Function<? super T, U> fn,
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Executor executor);

public CompletionStage<Void> acceptEither(CompletionStage<? extends T> other,
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Consumer<? super T> action);

public CompletionStage<Void> acceptEitherAsync(CompletionStage<? extends T> other,
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Consumer<? super T> action);

public CompletionStage<Void> acceptEitherAsync(CompletionStage<? extends T> other,
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Consumer<? super T> action,
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Executor executor);

public CompletionStage<Void> runAfterEither(CompletionStage<?> other,
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Runnable action);

public CompletionStage<Void> runAfterEitherAsync(CompletionStage<?> other,
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Runnable action);

public CompletionStage<Void> runAfterEitherAsync(CompletionStage<?> other,
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Runnable action,
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Executor executor);
  • applyToEither系列方法,入參類型為CompletionStageFunction
  • acceptEither系列方法,入參類型為CompletionStageConsumer
  • runAfterEither系列方法,入參類型為CompletionStageRunnable
private static void or() {
 ?CompletableFuture<Void> t1 =
 ? ? ?CompletableFuture.runAsync(
 ? ? ? ?  () -> {
 ? ? ? ? ? ?try {
 ? ? ? ? ? ? ?TimeUnit.SECONDS.sleep(10);
 ? ? ? ? ? ? ?System.out.println("t1");
 ? ? ? ? ?  } catch (Exception e) {
 ? ? ? ? ? ? ?throw new RuntimeException(e);
 ? ? ? ? ?  }
 ? ? ? ?  });

 ?CompletableFuture<Void> t2 =
 ? ? ?CompletableFuture.runAsync(
 ? ? ? ?  () -> {
 ? ? ? ? ? ?try {
 ? ? ? ? ? ? ?TimeUnit.SECONDS.sleep(200);
 ? ? ? ? ? ? ?System.out.println("t2");
 ? ? ? ? ?  } catch (Exception e) {
 ? ? ? ? ? ? ?throw new RuntimeException(e);
 ? ? ? ? ?  }
 ? ? ? ?  });

 ?CompletableFuture<String> t3 = t1.applyToEither(t2, s -> "applyToEither end");
 ?t3.thenAccept(System.out::println);
 ?t3.join();

 ?CompletableFuture<Void> t4 = t1.acceptEither(t2, s -> System.out.println("acceptEither end"));
 ?t4.join();

 ?CompletableFuture<Void> t5 =
 ? ? ?t1.runAfterEither(t2, () -> System.out.println("runAfterEither end"));
 ?t5.join();
}

描述異常關系

雖然fn、consumer、action它們的核心方法都不允許拋出可檢查異常,但是卻無法限制它們拋出運行時異常。

public CompletionStage<T> exceptionally(Function<Throwable, ? extends T> fn);

public CompletionStage<T> whenComplete(BiConsumer<? super T, ? super Throwable> action);
public CompletionStage<T> whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action);
public CompletionStage<T> whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action,
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Executor executor);

public <U> CompletionStage<U> handle(BiFunction<? super T, Throwable, ? extends U> fn);
public <U> CompletionStage<U> handleAsync(BiFunction<? super T, Throwable, ? extends U> fn);
public <U> CompletionStage<U> handleAsync(BiFunction<? super T, Throwable, ? extends U> fn,
 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Executor executor);
  • exceptionally系列方法,入參類型為Function<Throwable, T>。
  • whenComplete系列方法,入參類型為BiConsumer<T, Throwable>
  • handle系列方法,入參類型為BiFunction<T, Throwable, U>
private static void exception() {
 ?int i = 0;
 ?CompletableFuture<String> t1 =
 ? ? ?CompletableFuture.supplyAsync(
 ? ? ? ?  () -> {
 ? ? ? ? ? ?System.out.println("t1");
 ? ? ? ? ? ?if (i > 0) {
 ? ? ? ? ? ? ?return "t1";
 ? ? ? ? ?  }
 ? ? ? ? ? ?throw new RuntimeException("error");
 ? ? ? ?  });

 ?// ?  CompletableFuture<Void> t2 =
 ?// ? ? ?  t1.exceptionally(e -> e.getMessage())
 ?// ? ? ? ? ?  .thenAccept(System.out::println)
 ?// ? ? ? ? ?  .thenRun(() -> System.out.println("exceptionally end"));
 ?// ?  t2.join();

 ?// ?  CompletableFuture<String> t3 =
 ?// ? ? ?  t1.whenComplete(
 ?// ? ? ? ? ? ? ?  (s, e) -> {
 ?// ? ? ? ? ? ? ? ?  if (e != null) {
 ?// ? ? ? ? ? ? ? ? ?  System.out.println(e.getMessage());
 ?// ? ? ? ? ? ? ? ?  } else {
 ?// ? ? ? ? ? ? ? ? ?  System.out.println(s);
 ?// ? ? ? ? ? ? ? ?  }
 ?// ? ? ? ? ? ? ?  });
 ?// ?  t3.join();

 ?CompletableFuture<Void> t4 =
 ? ? ?t1.handle(
 ? ? ? ? ? ?  (s, e) -> {
 ? ? ? ? ? ? ? ?if (e != null) {
 ? ? ? ? ? ? ? ? ?return e.getMessage();
 ? ? ? ? ? ? ?  }
 ? ? ? ? ? ? ? ?return s;
 ? ? ? ? ? ?  })
 ? ? ? ?  .thenAccept(System.out::println);
 ?t4.join();
}

其余API

allOf() 與anyOf() 也是一對孿生兄弟,當我們需要對多個Future的運行進行組織時,就可以考慮使用它們:

  • allOf() :給定一組任務,等待所有任務執(zhí)行結束;
  • anyOf() :給定一組任務,等待其中任一任務執(zhí)行結束。
private static void all() {
 ?long startTime = System.currentTimeMillis();
 ?CompletableFuture<Void> t1 =
 ? ? ?CompletableFuture.runAsync(
 ? ? ? ?  () -> {
 ? ? ? ? ? ?try {
 ? ? ? ? ? ? ?TimeUnit.SECONDS.sleep(5);
 ? ? ? ? ? ? ?System.out.println("t1");
 ? ? ? ? ?  } catch (Exception e) {
 ? ? ? ? ? ? ?throw new RuntimeException(e);
 ? ? ? ? ?  }
 ? ? ? ?  });

 ?CompletableFuture<Void> t2 =
 ? ? ?CompletableFuture.runAsync(
 ? ? ? ?  () -> {
 ? ? ? ? ? ?try {
 ? ? ? ? ? ? ?TimeUnit.SECONDS.sleep(15);
 ? ? ? ? ? ? ?System.out.println("t2");
 ? ? ? ? ?  } catch (Exception e) {
 ? ? ? ? ? ? ?throw new RuntimeException(e);
 ? ? ? ? ?  }
 ? ? ? ?  });
 ?CompletableFuture<Void> t3 =
 ? ? ?CompletableFuture.allOf(t1, t2)
 ? ? ? ?  .thenRun(
 ? ? ? ? ? ?  () ->
 ? ? ? ? ? ? ? ? ?System.out.println(
 ? ? ? ? ? ? ? ? ? ? ?"all end cost " + (System.currentTimeMillis() - startTime) + " ms."));
 ?t3.join();
}

private static void any() {
 ?long startTime = System.currentTimeMillis();
 ?CompletableFuture<Void> t1 =
 ? ? ?CompletableFuture.runAsync(
 ? ? ? ?  () -> {
 ? ? ? ? ? ?try {
 ? ? ? ? ? ? ?TimeUnit.SECONDS.sleep(5);
 ? ? ? ? ? ? ?System.out.println("t1");
 ? ? ? ? ?  } catch (Exception e) {
 ? ? ? ? ? ? ?throw new RuntimeException(e);
 ? ? ? ? ?  }
 ? ? ? ?  });

 ?CompletableFuture<Void> t2 =
 ? ? ?CompletableFuture.runAsync(
 ? ? ? ?  () -> {
 ? ? ? ? ? ?try {
 ? ? ? ? ? ? ?TimeUnit.SECONDS.sleep(15);
 ? ? ? ? ? ? ?System.out.println("t2");
 ? ? ? ? ?  } catch (Exception e) {
 ? ? ? ? ? ? ?throw new RuntimeException(e);
 ? ? ? ? ?  }
 ? ? ? ?  });

 ?CompletableFuture<Void> t3 =
 ? ? ?CompletableFuture.anyOf(t1, t2)
 ? ? ? ?  .thenRun(
 ? ? ? ? ? ?  () ->
 ? ? ? ? ? ? ? ? ?System.out.println(
 ? ? ? ? ? ? ? ? ? ? ?"all end cost " + (System.currentTimeMillis() - startTime) + " ms."));
 ?t3.join();
}

經典案例

利用CompletableFuture來實現燒水泡茶程序,來自極客時間-java并發(fā)編程課程的案例

分工:

  • 任務1負責洗水壺,燒開水。
  • 任務2負責洗茶壺,洗茶杯,拿茶葉。
  • 任務1和任務2并行。
  • 任務1和任務3都完成后,啟動任務三泡茶。

// 任務 1:洗水壺 -> 燒開水
CompletableFuture<Void> f1 = 
 ?CompletableFuture.runAsync(()->{
 ?System.out.println("T1: 洗水壺...");
 ?sleep(1, TimeUnit.SECONDS);
?
 ?System.out.println("T1: 燒開水...");
 ?sleep(15, TimeUnit.SECONDS);
});
// 任務 2:洗茶壺 -> 洗茶杯 -> 拿茶葉
CompletableFuture<String> f2 = 
 ?CompletableFuture.supplyAsync(()->{
 ?System.out.println("T2: 洗茶壺...");
 ?sleep(1, TimeUnit.SECONDS);
?
 ?System.out.println("T2: 洗茶杯...");
 ?sleep(2, TimeUnit.SECONDS);
?
 ?System.out.println("T2: 拿茶葉...");
 ?sleep(1, TimeUnit.SECONDS);
 ?return " 龍井 ";
});
// 任務 3:任務 1 和任務 2 完成后執(zhí)行:泡茶
CompletableFuture<String> f3 = 
 ?f1.thenCombine(f2, (__, tf)->{
 ? ?System.out.println("T1: 拿到茶葉:" + tf);
 ? ?System.out.println("T1: 泡茶...");
 ? ?return " 上茶:" + tf;
  });
// 等待任務 3 執(zhí)行結果
System.out.println(f3.join());
?
void sleep(int t, TimeUnit u) {
 ?try {
 ? ?u.sleep(t);
  }catch(InterruptedException e){}
}

一次執(zhí)行結果:

T1: 洗水壺...
T2: 洗茶壺...
T1: 燒開水...
T2: 洗茶杯...
T2: 拿茶葉...
T1: 拿到茶葉: 龍井
T1: 泡茶...
上茶: 龍井

到此這篇關于Java如何利用CompletableFuture描述任務之間的關系的文章就介紹到這了,更多相關Java CompletableFuture內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • RabbitMQ交換機使用場景和消息可靠性總結分析

    RabbitMQ交換機使用場景和消息可靠性總結分析

    這篇文章主要為大家介紹了RabbitMQ交換機使用場景和消息可靠性總結分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-01-01
  • Nacos配置中心搭建及動態(tài)刷新配置及踩坑記錄

    Nacos配置中心搭建及動態(tài)刷新配置及踩坑記錄

    這篇文章主要介紹了Nacos配置中心搭建及動態(tài)刷新配置及踩坑記錄,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • Java設計模式之java狀態(tài)模式詳解

    Java設計模式之java狀態(tài)模式詳解

    這篇文章主要介紹了Java設計模式之狀態(tài)模式定義與用法,結合具體實例形式詳細分析了Java狀態(tài)模式的概念、原理、定義及相關操作技巧,需要的朋友可以參考下
    2021-09-09
  • 零基礎全面解析SpringBoot配置文件(結合驗證碼案例)

    零基礎全面解析SpringBoot配置文件(結合驗證碼案例)

    文章介紹配置文件的作用及SpringBoot中properties和yml格式的使用,比較其優(yōu)缺點,并演示基于Hutool的驗證碼生成與校驗實現,本文結合驗證碼案例給大家詳細講解,感興趣的朋友跟隨小編一起看看吧
    2025-09-09
  • @Valid和@Validated注解校驗以及異常處理方式

    @Valid和@Validated注解校驗以及異常處理方式

    在Javaweb開發(fā)中,防止數據庫惡意攻擊是至關重要的,盡管前端校驗可以起到一定的篩選作用,但通過工具如postman直接對后端發(fā)起請求的情況仍然需要后端進行嚴格的數據校驗,Java生態(tài)下,@Valid注解配合SpringBoot提供了一個便捷高效的后端數據校驗方案
    2024-11-11
  • Mybatis-Plus 映射匹配兼容性的問題解決

    Mybatis-Plus 映射匹配兼容性的問題解決

    本文主要介紹了Mybatis-Plus 映射匹配兼容性的問題解決,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-01-01
  • spring配置掃描多個包問題解析

    spring配置掃描多個包問題解析

    這篇文章主要介紹了spring配置掃描多個包問題解析,具有一定參考價值,需要的朋友可以了解下。
    2017-10-10
  • Java基礎之關鍵字final詳解

    Java基礎之關鍵字final詳解

    這篇文章主要介紹了Java基礎之關鍵字final詳解,文中有非常詳細的代碼示例,對正在學習java基礎的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-05-05
  • Java實現產生隨機字符串主鍵的UUID工具類

    Java實現產生隨機字符串主鍵的UUID工具類

    這篇文章主要介紹了Java實現產生隨機字符串主鍵的UUID工具類,涉及java隨機數與字符串遍歷、轉換等相關操作技巧,需要的朋友可以參考下
    2017-10-10
  • Spring中的@AliasFor標簽的用法及說明

    Spring中的@AliasFor標簽的用法及說明

    Spring框架中的@AliasFor標簽用于定義注解屬性的別名,使得在同一個注解中可以使用相同的屬性值,從而提高代碼的可讀性和可維護性
    2026-03-03

最新評論

宁乡县| 青阳县| 永丰县| 保德县| 西平县| 赤水市| 九龙城区| 当阳市| 平安县| 保德县| 福泉市| 屏东县| 昌吉市| 玛沁县| 新密市| 嘉义县| 韩城市| 琼结县| 林周县| 江永县| 边坝县| 资兴市| 石城县| 和平区| 北川| 任丘市| 阳新县| 临潭县| 明光市| 靖远县| 安义县| 扶绥县| 汉阴县| 交城县| 临海市| 武陟县| 承德市| 九龙坡区| 滨海县| 罗甸县| 古蔺县|