Class ScopedValueUtil

java.lang.Object
cn.toint.oktool.util.ScopedValueUtil

public class ScopedValueUtil extends Object
ScopedValue 异步传播工具类

用于在异步任务(CompletableFuture)中传播 JDK 21+ 的 ScopedValue, 解决 ScopedValue 在跨线程时值丢失的问题。

使用示例:

ScopedValue<String> USER_ID = ScopedValue.newInstance();

ScopedValue.where(USER_ID, "user123").run(() -> {
    // 异步任务中自动传播 USER_ID
    ScopedValueUtil.supplyAsync(USER_ID, () -> {
        return "Processing for: " + USER_ID.get();
    }).thenAccept(System.out::println);
});
Since:
2025/10/21
Author:
Toint
  • Constructor Details

    • ScopedValueUtil

      public ScopedValueUtil()
  • Method Details

    • runAsync

      public static <V> CompletableFuture<Void> runAsync(ScopedValue<V> scopedValue, Runnable runnable)
      在异步任务中传播单个 ScopedValue(无返回值)

      捕获当前线程中指定 ScopedValue 的值,并在异步任务中恢复该值的绑定。

      Type Parameters:
      V - ScopedValue 的值类型
      Parameters:
      scopedValue - 需要传播的 ScopedValue
      runnable - 异步执行的任务
      Returns:
      CompletableFuture 异步任务的 Future 对象
    • supplyAsync

      public static <V,R> CompletableFuture<R> supplyAsync(ScopedValue<V> scopedValue, Supplier<R> supplier)
      在异步任务中传播单个 ScopedValue(有返回值)

      捕获当前线程中指定 ScopedValue 的值,并在异步任务中恢复该值的绑定。

      Type Parameters:
      V - ScopedValue 的值类型
      R - 异步任务的返回值类型
      Parameters:
      scopedValue - 需要传播的 ScopedValue
      supplier - 异步执行的任务,返回结果
      Returns:
      CompletableFuture 异步任务的 Future 对象,包含任务执行结果
    • runAsync

      public static CompletableFuture<Void> runAsync(List<ScopedValue<?>> scopedValues, Runnable runnable)
      在异步任务中传播多个 ScopedValue(无返回值)

      捕获当前线程中多个 ScopedValue 的值,并在异步任务中恢复这些值的绑定。 只有已绑定的 ScopedValue 会被传播,未绑定的会被忽略。

      Parameters:
      scopedValues - 需要传播的 ScopedValue 列表(可以包含不同类型的 ScopedValue)
      runnable - 异步执行的任务
      Returns:
      CompletableFuture 异步任务的 Future 对象
    • supplyAsync

      public static <R> CompletableFuture<R> supplyAsync(List<ScopedValue<?>> scopedValues, Supplier<R> supplier)
      在异步任务中传播多个 ScopedValue(有返回值)

      捕获当前线程中多个 ScopedValue 的值,并在异步任务中恢复这些值的绑定。 只有已绑定的 ScopedValue 会被传播,未绑定的会被忽略。

      Type Parameters:
      R - 异步任务的返回值类型
      Parameters:
      scopedValues - 需要传播的 ScopedValue 列表(可以包含不同类型的 ScopedValue)
      supplier - 异步执行的任务,返回结果
      Returns:
      CompletableFuture 异步任务的 Future 对象,包含任务执行结果
    • supplyAsync

      public static <R> CompletableFuture<R> supplyAsync(Map<ScopedValue<?>, Object> scopedValueMap, Supplier<R> supplier)
      在异步任务中传播 ScopedValue 上下文(有返回值)

      根据提供的 ScopedValue 上下文映射,在异步任务中恢复这些值的绑定。 这是最底层的传播方法,其他 supplyAsync 方法最终都会调用此方法。

      Type Parameters:
      R - 异步任务的返回值类型
      Parameters:
      scopedValueMap - ScopedValue 到其值的映射,表示需要传播的上下文
      supplier - 异步执行的任务,返回结果
      Returns:
      CompletableFuture 异步任务的 Future 对象,包含任务执行结果
      Throws:
      NullPointerException - 如果 supplier 为 null
    • runAsync

      public static CompletableFuture<Void> runAsync(Map<ScopedValue<?>, Object> scopedValueMap, Runnable runnable)
      在异步任务中传播 ScopedValue 上下文(无返回值)

      根据提供的 ScopedValue 上下文映射,在异步任务中恢复这些值的绑定。 这是最底层的传播方法,其他 runAsync 方法最终都会调用此方法。

      Parameters:
      scopedValueMap - ScopedValue 到其值的映射,表示需要传播的上下文
      runnable - 异步执行的任务
      Returns:
      CompletableFuture 异步任务的 Future 对象
      Throws:
      NullPointerException - 如果 runnable 为 null
    • buildCarrier

      public static ScopedValue.Carrier buildCarrier(Map<ScopedValue<?>, Object> scopedValueMap)
      构建 ScopedValue.Carrier 对象

      Carrier 用于在新的执行上下文中批量绑定多个 ScopedValue。 通过链式调用 where() 方法构建包含所有绑定的 Carrier。

      Parameters:
      scopedValueMap - ScopedValue 到其值的映射
      Returns:
      ScopedValue.Carrier 对象,如果映射为空则返回 null
    • captureContext

      public static Map<ScopedValue<?>, Object> captureContext(List<ScopedValue<?>> scopedValues)
      捕获当前线程中已绑定的 ScopedValue

      遍历指定的 ScopedValue 列表,提取所有在当前线程中已绑定的值, 构建成 Map 以便后续在异步线程中恢复。未绑定或为 null 的 ScopedValue 会被忽略。

      Parameters:
      scopedValues - 需要捕获的 ScopedValue 列表(可以包含不同类型的 ScopedValue)
      Returns:
      Map<ScopedValue<?>, Object> 包含已绑定值的映射,如果没有绑定值则返回空 Map
    • get

      public static <V> Optional<V> get(ScopedValue<V> scopedValue)
      安全获取 ScopedValue 的绑定值

      ScopedValue.get() 不同,此方法在 ScopedValue 未绑定时返回 Optional.empty(), 而不是抛出 NoSuchElementException 异常。适用于需要容错处理的场景。

      使用场景:

      • 不确定 ScopedValue 是否已绑定时
      • 需要优雅处理未绑定情况,避免异常
      • 可选的上下文传递场景

      使用示例:

      ScopedValue<String> USER_ID = ScopedValue.newInstance();
      
      // 安全获取,不会抛异常
      ScopedValueUtil.get(USER_ID).ifPresent(userId -> {
          System.out.println("User ID: " + userId);
      });
      
      Type Parameters:
      V - ScopedValue 的值类型
      Parameters:
      scopedValue - 需要获取值的 ScopedValue,允许为 null
      Returns:
      Optional 包装的值
      See Also:
    • getOrNull

      public static <V> V getOrNull(ScopedValue<V> scopedValue)
      安全获取 ScopedValue 的绑定值

      ScopedValue.get() 不同,此方法在 ScopedValue 未绑定时返回 null, 而不是抛出 NoSuchElementException 异常。适用于需要容错处理的场景。

      使用场景:

      • 不确定 ScopedValue 是否已绑定时
      • 需要优雅处理未绑定情况,避免异常
      • 可选的上下文传递场景

      使用示例:

      ScopedValue<String> USER_ID = ScopedValue.newInstance();
      
      // 安全获取,不会抛异常
      String userId = ScopedValueUtil.getOrNull(USER_ID);
      if (userId != null) {
          System.out.println("User ID: " + userId);
      }
      
      Type Parameters:
      V - ScopedValue 的值类型
      Parameters:
      scopedValue - 需要获取值的 ScopedValue,允许为 null
      Returns:
      已绑定的值,如果未绑定或 scopedValue 为 null 则返回 null
      See Also:
    • orElse

      public static <V> V orElse(ScopedValue<V> scopedValue, V defaultValue)
      安全获取 ScopedValue 的绑定值,若未绑定则返回默认值

      ScopedValue.get() 不同,此方法在 ScopedValue 未绑定时返回指定的默认值, 而不是抛出 NoSuchElementException 异常。适用于需要提供后备值的场景。

      使用场景:

      • 需要为未绑定的 ScopedValue 提供后备值
      • 避免显式的 null 检查,直接提供默认值
      • 链式调用或函数式编程中简化逻辑

      使用示例:

      ScopedValue<String> USER_ROLE = ScopedValue.newInstance();
      
      // 获取用户角色,未绑定时返回 "guest"
      String role = ScopedValueUtil.orElse(USER_ROLE, "guest");
      System.out.println("User role: " + role); // 输出 "guest"(若未绑定)
      
      Type Parameters:
      V - ScopedValue 的值类型
      Parameters:
      scopedValue - 需要获取值的 ScopedValue,允许为 null
      defaultValue - 当 ScopedValue 未绑定或为 null 时返回的默认值
      Returns:
      已绑定的值,如果未绑定或 scopedValue 为 null 则返回 defaultValue
      See Also:
    • isBound

      public static <V> boolean isBound(ScopedValue<V> scopedValue)
      安全判断指定的 ScopedValue 是否已绑定到当前线程的上下文。

      此方法提供空安全检查,避免直接调用 scopedValue.isBound() 时可能出现的 NullPointerException

      典型使用场景:

      if (ScopedValueUtils.isBound(CONTEXT_KEY)) {
          // 已绑定时执行逻辑
      }
      
      Type Parameters:
      V - ScopedValue 的泛型类型
      Parameters:
      scopedValue - 要检查的 ScopedValue 实例,允许为 null
      Returns:
      true 如果 scopedValue 非空且已绑定到当前线程; false 如果 scopedValuenull 或未绑定
      See Also: