ThreadLocal 常用方式之一 | LIXI.FUN
0%

ThreadLocal 常用方式之一

AOP 拦截了 JWT 解出来的用户信息如何在 Controller - Service 之间传递?

使用 ThreadLocal 保存线程内的共享变量。

以下为演示代码,去除了具体的解析过程和异常处理信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@Slf4j
@Aspect
@Component
public class JWTAspect {

@Pointcut("execution(* com.nevertrouble.xxx.controller.*.*(..))")
public void exe() {}

@Around("exe()")
public Object doAround(ProceedingJoinPoint pjp) {

// 从请求中拿到 JWT ,解出 UserInfo
UserInfo userInfo = ...;

// 在 UserContextHolder 中设置 ThreadLocal<UserInfo> 的值为解出来的值
UserContextHolder.setUserInfo(userInfo);

Object result = pjp.proceed();

// 一定要 clear()
UserContextHolder.clear();
return result;
}

}

UserContextHolder 的具体实现,Spring-security 同样也是用这种方式来做的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class UserContextHolder {

private static final ThreadLocal<UserInfo> USER_INFO = new ThreadLocal<>();

public static void setUserInfo(UserInfo userInfo) {
USER_INFO.set(userInfo);
}

public static void clear() {
USER_INFO.remove();
}

public static UserInfo getUserInfo() {
return USER_INFO.get();
}
}

接下来不管是在 Controller 还是 Service 中,只要还是在 同一个线程(很重要) 如果需要 UserInfo 就可以使用 UserContextHolder.getUserInfo() 获取当前请求中的用户信息。

觉得有收获就鼓励下作者吧