AOP 拦截了 JWT 解出来的用户信息如何在 Controller - Service
之间传递?
使用 ThreadLocal 保存线程内的共享变量。
以下为演示代码,去除了具体的解析过程和异常处理信息。
@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 同样也是用这种方式来做的。
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()
获取当前请求中的用户信息。