Skip to content

Commit 5a3060b

Browse files
committed
feat: 增加新的ContextHolder上下文支持
1 parent 4d164df commit 5a3060b

File tree

4 files changed

+126
-1
lines changed

4 files changed

+126
-1
lines changed

hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/token/UserTokenHolder.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.hswebframework.web.authorization.token;
22

33

4+
import org.hswebframework.web.context.ContextHolder;
45
import org.hswebframework.web.context.ContextUtils;
56

67
/**
@@ -12,7 +13,7 @@ private UserTokenHolder() {
1213
}
1314

1415
public static UserToken currentToken() {
15-
return ContextUtils.currentContext().get(UserToken.class).orElse(null);
16+
return ContextHolder.current().getOrDefault(UserToken.class,null);
1617
}
1718

1819
public static UserToken setCurrent(UserToken token) {

hsweb-core/src/main/java/org/hswebframework/web/context/Context.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import java.util.Optional;
55
import java.util.function.Supplier;
66

7+
@Deprecated
78
public interface Context {
89

910
default <T> Optional<T> get(Class<T> key) {
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package org.hswebframework.web.context;
2+
3+
import lombok.SneakyThrows;
4+
import reactor.core.publisher.Mono;
5+
import reactor.util.context.Context;
6+
import reactor.util.context.ContextView;
7+
8+
import java.io.Closeable;
9+
import java.lang.reflect.UndeclaredThrowableException;
10+
import java.util.Collections;
11+
import java.util.Comparator;
12+
import java.util.List;
13+
import java.util.ServiceLoader;
14+
import java.util.concurrent.Callable;
15+
import java.util.function.Function;
16+
import java.util.stream.Collectors;
17+
18+
public class ContextHolder {
19+
20+
private static final List<ContextHolderSupport> supports;
21+
22+
static {
23+
supports = ServiceLoader
24+
.load(ContextHolderSupport.class)
25+
.stream()
26+
.map(ServiceLoader.Provider::get)
27+
.collect(Collectors.toList());
28+
supports.add(new ThreadLocalContextHolderSupport());
29+
supports.sort(Comparator.comparingInt(ContextHolderSupport::order));
30+
}
31+
32+
public static Closeable makeCurrent(ContextView context) {
33+
for (ContextHolderSupport support : supports) {
34+
if (support.isSupport()) {
35+
return support.makeCurrent(context);
36+
}
37+
}
38+
throw new UnsupportedOperationException();
39+
40+
}
41+
42+
@SneakyThrows
43+
public static <T> T doInContext(Context context, Callable<T> call) {
44+
try (Closeable ignore = makeCurrent(context)) {
45+
return call.call();
46+
} catch (UndeclaredThrowableException e) {
47+
throw e.getCause();
48+
}
49+
}
50+
51+
public static <T> Mono<T> currentReactive(Function<ContextView, Mono<T>> handler) {
52+
return Mono.deferContextual(ctx -> handler.apply(current().putAll(ctx)));
53+
}
54+
55+
public static Context current() {
56+
for (ContextHolderSupport support : supports) {
57+
if (support.isSupport()) {
58+
return support.current();
59+
}
60+
}
61+
throw new UnsupportedOperationException();
62+
}
63+
64+
public interface ContextHolderSupport {
65+
boolean isSupport();
66+
67+
Closeable makeCurrent(ContextView context);
68+
69+
void clean();
70+
71+
Context current();
72+
73+
default int order() {
74+
return Integer.MIN_VALUE;
75+
}
76+
}
77+
78+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package org.hswebframework.web.context;
2+
3+
import reactor.util.context.Context;
4+
import reactor.util.context.ContextView;
5+
6+
import java.io.Closeable;
7+
8+
/**
9+
* 基于 ThreadLocal 的上下文持有器支持实现
10+
* 适用于传统平台线程环境
11+
*/
12+
public class ThreadLocalContextHolderSupport implements ContextHolder.ContextHolderSupport {
13+
14+
private static final ThreadLocal<Context> contextHolder = ThreadLocal.withInitial(Context::empty);
15+
16+
@Override
17+
public boolean isSupport() {
18+
return true;
19+
}
20+
21+
@Override
22+
public Closeable makeCurrent(ContextView context) {
23+
Context previous = contextHolder.get();
24+
Context newContext = previous.putAll(context);
25+
contextHolder.set(newContext);
26+
27+
return () -> contextHolder.set(previous);
28+
}
29+
30+
@Override
31+
public void clean() {
32+
contextHolder.remove();
33+
}
34+
35+
@Override
36+
public Context current() {
37+
Context context = contextHolder.get();
38+
return context != null ? context : Context.empty();
39+
}
40+
41+
@Override
42+
public int order() {
43+
return Integer.MAX_VALUE; // 最低优先级,作为回退选项
44+
}
45+
}

0 commit comments

Comments
 (0)