- 자바의 class 중 하나.
- 오직 한 쓰레드에 의해서 읽고 쓰여질 수 있는 변수
- 두개 이상의 쓰레드가 같은 코드를 실행하고 이 코드가 하나의 ThreadLocal 변수를 참조 하더라도 서로의 ThreadLocal 변수를 볼 수 없음
- 👉멀티 쓰레드 환경에서 각 스레드마다 독립적인 변수를 가지고 접근할 수 있음.
사용 방법
- Context 클래스에서 ThreadLocal 객체를 생성한다.
- ThreadLocal.set() 메서드를 이용해서 현재 쓰레드의 로컬 변수에 값을 저장한다.
- ThreadLocal.get() 메서드를 이용해서 현재 쓰레드의 로컬 변수 값을 읽어온다.
- ThreadLocal.remove() 메서드를 이용해서 현재 쓰레드의 로컬 변수 값을 삭제한다.
자세한 내용 : https://javacan.tistory.com/entry/ThreadLocalUsage 참고
활용 방법
한 쓰레드에서 실행되는 코드가 동일한 객체를 사용할 수 있도록 해주기 때문에, 관련된 코드에서 메소드 파라미터를 사용하지 않고 객체를 각자가 가져다 쓸 때 사용 가능
- 사용자 인증 정보 Spring Security에서 사용자마다 다른 인증 정보를 사용할 때 & Session 정보
- 쓰레드에 안전해야 하는 데이터를 보관 할 때
- Spring Security 사용 시, SecurityContextHolder.getContext().getAuthentication() 을 통해 메소드의 파라미터나 클래스의 변수 없이도 현재 인증된 유저에 대한 정보를 가져올 수 있음.
- SecurityContextHolder가 기본적으로 ThreadLocal 전략을 사용하고 있기에 가능.
예제
// UserAccount를 ThreadLocal에 저장해 사용하는 Custom한 UserContext
public class UserContext {
// UserAccount를 담는 ThreadLocal 정의
private static ThreadLocal<UserAccount> THREAD_LOCAL_ACCOUNT = new ThreadLocal<UserAccount>();
public static UserAccount getUserAccount() {
return THREAD_LOCAL_ACCOUNT.get();
}
// 인증된 유저를 ThreadLocal에 담기.
public static void setUserAccount(UserAccount userAccount) {
THREAD_LOCAL_ACCOUNT.set(userAccount);;
}
}
@PostMapping("/info/delete")
public ModelAndView registrationInfo(ModelAndView mv) {
//파라미터 없이도 현재 UserContext에 저장된 인증 처리된 UserAccount를 가져와 사용 가능
UserAccount user = UserContext.getUserAccount();
registrationClientInfoService.delete(user.getUsername);
mv.setViewName("client/info");
return mv;
}
주의할 점
- Thread pool 환경에서 ThreadLocal을 사용하므로, 데이터 사용이 끝나면 반드시 .remove()를 통해 데이터를 삭젷줘야 함
- ThreadLocal은 static으로 정의해야 함. 그렇지 않으면, 하나의 Thread 안에서 값이 다르게 나옴.
참고 : https://nathanh.tistory.com/131
ThreadLocal 이란?
Intro Spring Security를 사용하다 보면, 인증이 된 유저는 UsetDetailsService 에서 리턴을 한 후 UserDetails 타입의 객체가 바로 Principal 로 변환되어 사용하게 된다. 즉 인증이 된 유저는 Principal이 되고..
nathanh.tistory.com
'프로젝트 기록' 카테고리의 다른 글
Entity type으로 Wrapper class를 사용하는 이유 (0) | 2022.02.23 |
---|---|
정적 팩토리 메서드 (0) | 2022.02.23 |
기타 에러 해결 기록들 (0) | 2022.02.23 |
JPA N+1 문제 해결 (0) | 2022.02.23 |
REST API 가이드 (0) | 2022.02.23 |