Class ScopedValueUtil
用于在异步任务(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 Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionstatic ScopedValue.CarrierbuildCarrier(Map<ScopedValue<?>, Object> scopedValueMap) 构建 ScopedValue.Carrier 对象static Map<ScopedValue<?>, Object> captureContext(List<ScopedValue<?>> scopedValues) 捕获当前线程中已绑定的 ScopedValuestatic <V> Optional<V> get(ScopedValue<V> scopedValue) 安全获取 ScopedValue 的绑定值static <V> VgetOrNull(ScopedValue<V> scopedValue) 安全获取 ScopedValue 的绑定值static <V> booleanisBound(ScopedValue<V> scopedValue) 安全判断指定的ScopedValue是否已绑定到当前线程的上下文。static <V> VorElse(ScopedValue<V> scopedValue, V defaultValue) 安全获取 ScopedValue 的绑定值,若未绑定则返回默认值static <V> CompletableFuture<Void> runAsync(ScopedValue<V> scopedValue, Runnable runnable) 在异步任务中传播单个 ScopedValue(无返回值)static CompletableFuture<Void> runAsync(List<ScopedValue<?>> scopedValues, Runnable runnable) 在异步任务中传播多个 ScopedValue(无返回值)static CompletableFuture<Void> runAsync(Map<ScopedValue<?>, Object> scopedValueMap, Runnable runnable) 在异步任务中传播 ScopedValue 上下文(无返回值)static <V,R> CompletableFuture <R> supplyAsync(ScopedValue<V> scopedValue, Supplier<R> supplier) 在异步任务中传播单个 ScopedValue(有返回值)static <R> CompletableFuture<R> supplyAsync(List<ScopedValue<?>> scopedValues, Supplier<R> supplier) 在异步任务中传播多个 ScopedValue(有返回值)static <R> CompletableFuture<R> supplyAsync(Map<ScopedValue<?>, Object> scopedValueMap, Supplier<R> supplier) 在异步任务中传播 ScopedValue 上下文(有返回值)
-
Constructor Details
-
ScopedValueUtil
public ScopedValueUtil()
-
-
Method Details
-
runAsync
在异步任务中传播单个 ScopedValue(无返回值)捕获当前线程中指定 ScopedValue 的值,并在异步任务中恢复该值的绑定。
- Type Parameters:
V- ScopedValue 的值类型- Parameters:
scopedValue- 需要传播的 ScopedValuerunnable- 异步执行的任务- 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- 需要传播的 ScopedValuesupplier- 异步执行的任务,返回结果- 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
构建 ScopedValue.Carrier 对象Carrier 用于在新的执行上下文中批量绑定多个 ScopedValue。 通过链式调用 where() 方法构建包含所有绑定的 Carrier。
- Parameters:
scopedValueMap- ScopedValue 到其值的映射- Returns:
- ScopedValue.Carrier 对象,如果映射为空则返回 null
-
captureContext
捕获当前线程中已绑定的 ScopedValue遍历指定的 ScopedValue 列表,提取所有在当前线程中已绑定的值, 构建成 Map 以便后续在异步线程中恢复。未绑定或为 null 的 ScopedValue 会被忽略。
- Parameters:
scopedValues- 需要捕获的 ScopedValue 列表(可以包含不同类型的 ScopedValue)- Returns:
Map<ScopedValue<?>, Object>包含已绑定值的映射,如果没有绑定值则返回空 Map
-
get
安全获取 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
安全获取 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
安全获取 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,允许为 nulldefaultValue- 当 ScopedValue 未绑定或为 null 时返回的默认值- Returns:
- 已绑定的值,如果未绑定或 scopedValue 为 null 则返回 defaultValue
- See Also:
-
isBound
安全判断指定的ScopedValue是否已绑定到当前线程的上下文。此方法提供空安全检查,避免直接调用
scopedValue.isBound()时可能出现的NullPointerException。典型使用场景:
if (ScopedValueUtils.isBound(CONTEXT_KEY)) { // 已绑定时执行逻辑 }- Type Parameters:
V- ScopedValue 的泛型类型- Parameters:
scopedValue- 要检查的ScopedValue实例,允许为null- Returns:
true如果scopedValue非空且已绑定到当前线程;false如果scopedValue为null或未绑定- See Also:
-