SpringBoot之ThreadLocal儲存請求使用者資訊

奋--斗發表於2024-05-30

一、ThreadLocal概述

執行緒區域性變數,建立一個執行緒變數後,針對這個變數可以讓每個執行緒擁有自己的變數副本,每個執行緒是訪問的自己的副本,與其他執行緒的相互獨立。

二、具體程式碼demo實現

(1)建立user例項物件

@Data
public class UserDTO {
    private Long userId;
    private String UserName;
}

(2)建立UserThreadLocal物件

public class UserThreadLocal {

    private UserThreadLocal(){};

    private static final ThreadLocal<UserDTO> USER_DTO_THREAD_LOCAL = new ThreadLocal<>();

    /**
     * 清除資訊
     */
    public static void clear(){
        USER_DTO_THREAD_LOCAL.remove();
    }

    /**
     * 儲存使用者資訊
     * @param userDTO
     */
    public static void set(UserDTO userDTO){
        USER_DTO_THREAD_LOCAL.set(userDTO);
    }

    public static UserDTO getCurrentUser(){
       return USER_DTO_THREAD_LOCAL.get();
    }
}

(3)建立使用者攔截器

@Component
public class UserInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //此處實際應該根據header的token解析出使用者本處為了簡單,直接虛構一個使用者
        UserDTO userDTo = new UserDTO();
        userDTo.setUserId(10001L);
        userDTo.setUserName("張三");
        UserThreadLocal.set(userDTo);
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        UserThreadLocal.clear();
    }
}

(4) 註冊使用者攔截器

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new UserInterceptor());
    }
}

(5)編寫測試介面

@RequestMapping("test")
@RestController
public class TestController {

    @GetMapping("get")
    public UserDTO getUser(){
        UserDTO currentUser = UserThreadLocal.getCurrentUser();
        System.out.println(currentUser);
        return currentUser;
    }
}

(6)效果展示

localhost:8080/test/get

相關文章