티스토리 뷰
개발시 소스 전체에서 사용할 수 있는 전역변수처럼 데이터를 할당하고 싶을떄가 있습니다.
Threadlocal을 이용하여 이를 구현해 봅니다.
ShoppingController.java
@RestController public class ShoppingController { private int melon; @RequestMapping("/") private String test() { this.addMelon(); return String.valueOf(melon); } private void addMelon() { melon++; } }
사용자별로 요청 시 카트에 멜론을 담는 기능을 구현하려고 합니다. 이 떄 카트 수량은 여러 메소드에서 사용할 수 있기 때문에 멤버변수로 선언을 합니다.
이렇게 작성 후 실행을 해보면 카운트가 초기화가 되지 않고 계속 증가하는 것을 볼 수 있습니다. 스프링의 경우 빈 관리를 싱글톤으로 하기 때문에 ShoppingController 객체는 요청 시 재사용 됩니다. 멤버변수 역시 초기화가 되지 않습니다.
아래는 Threadlocal을 이용해 사용자별 카트를 구현한 소스입니다.
ThreadRepository.java
public class ThreadRepository { private static ThreadLocal<Cart> threadLocal = new ThreadLocal<Cart>() { @Override protected Cart initialValue() { return new Cart(); }; }; public static Cart getCart() { return threadLocal.get(); } public static void remove() { threadLocal.remove(); } }
카트를 담을 저장소를 만들어 줍니다. Thradlocal을 이용하여 Thread별로 저장소가 생성이 됩니다.
Cart.java
public class Cart { private int apple = 0; private int orange = 0; private int melon = 0; public void addApple() { this.apple++; } public void addOrange() { this.orange++; } public void addMelon() { this.melon++; } @Override public String toString() { return "Cart [apple=" + apple + ", orange=" + orange + ", melon=" + melon + "]"; } }
카트를 생성해줍니다.
ShoppingController.java
@RestController public class ShoppingController { @RequestMapping("/") private String test() { ThreadRepository.remove(); this.addMelon(); return ThreadRepository.getCart().toString(); } private void addMelon() { ThreadRepository.getCart().addMelon(); } }
컨트롤러가 위처럼 수정되었습니다. ThreadRepository에서 getCart를 했을때 해당 요청 쓰래드에 대한 Cart가 나오기 때문에 소스 어떤부분에서든 해당 카트의 데이터를 넣고 빼는 것이 가능합니다.
이때 ThreadLocal을 이용하였기 때문에 요청 시 새로운 스래드가 생성되며 그 스래드에서만 사용할 수 있게 관리됩니다.
* 일반으로 WAS는 쓰래드풀을 쓰기 때문에 요청이나 응답 시 해당 Threadlocal을 초기화 하지 않을 경우 이전에 사용한 정보가 남아 있습니다. 쓰래드 재사용시 반드시 remove를 통해 초기화 시켜주어야 합니다.
참고소스
https://github.com/donnert/spring-boot/tree/master/thread-local
'개발 > Java, Kotlin' 카테고리의 다른 글
spring profile 사용시 주의점 (0) | 2018.03.26 |
---|---|
@Scope 어노테이션 사용하기(request+ProxyMode) (0) | 2018.02.06 |
한글 byte로 자르기(깨짐 없이) (0) | 2017.06.30 |
이클립스 플러그인(vrapper) 설정파일(vrapperrc) (0) | 2017.01.26 |
스프링 부트(spring boot)로 톰캣에서 실행하기(이클립스) (0) | 2016.11.03 |
- Total
- Today
- Yesterday
- Shell
- boot
- oracle
- java
- Kotlin
- docker
- 톰캣
- Spring
- mybatis
- Build
- vim
- Eclipse
- Database
- 코틀린
- Access
- properties
- Profile
- vrapper
- grant
- ls
- jQuery
- vi
- 맛집
- Linux
- 도커
- resttemplate
- 합정
- Tomcat
- maven
- IntelliJ
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 26 | 27 | 28 |
29 | 30 |