스프링 빈과 Thread-Safe
스프링에서 빈을 생성할 때 빈의 Scope(생명주기)은 싱글톤이다. 해당 빈 생성은 디폴트이다.
Prototype, request, session 등 다양하게 존재한다.
여기서 잠깐 싱글톤이 뭔지 지고 넘어가자.
싱글톤 패턴은 생성자가 여러 차례 호출되더라도 결국 실제로 생성되는 객체는 하나이고, 최초 생성한 객체를 계속 리턴한다. 보통 Java 에서의 getInstace() 메소드는 “보통” 싱글톤을 의미한다(다 그렇지는 않다).
즉, Spring에서 @Components, @Service, @Controller, @Repository 등의 모든 빈들은 WAS가 가동할 때 싱글톤으로 객체를 인스턴스화 후, Spring Container에 보관한다(IoC 행위). 그 다음은 우리는 Inject를 통해 사용한다(DI 행위).
여기서 질문은 다음과 같다.
아니, Controller나 Service 객체가 1개인데 멀티 쓰레드 환경에서 Thread-Safe하게 어플리케이션을 어떻게 운용하냐? 그리고 Spring Bean은 Thread-Safe 하냐??
일단 답은 No이다. Spring 빈은 Thread-Safe하지 않다.
Thread-Safe하게 사용하면 Yes이고, 그렇지 않으면 No이다. 다음과 같이 맴버 변수를 사용하면 Thread-Safe하지 않다.
그럼 어떻게 사용해야하는가?
빈을 불변하도록 한다(Immutable).
1. Constructor Inject 사용한다.
2. Builder 패턴을 활용한다.
3. 빈에 대해 Setter를 허용하지 않는다.
빈은 무상태여야 한다(Stateless).
빈의 특정 상태를 나타내는 변수를 계속 힙메모리에 상주시키면 안된다(위의 Calculator와 같은 행동).
참고
https://stackoverflow.com/questions/15745140/are-spring-objects-thread-safe
https://alwayspr.tistory.com/11
https://beyondj2ee.wordpress.com/2013/02/28/멀티-쓰레드-환경에서-스프링빈-주의사항/
https://javacan.tistory.com/entry/ThreadLocalUsage
'개발관련 > (과거)메모' 카테고리의 다른 글
JUnit과 함께하는 AssertJ (0) | 2019.11.12 |
---|---|
Hashed Data RSA 서명할 때 주의사항 (0) | 2019.10.01 |
mybatis- "IllegalArgumentException: invalid comparison: java.util.Date and java.lang.String (2) | 2019.06.28 |
Integer.ParseInt() vs Integer.valueof() (1) | 2017.05.08 |
자바 Reflect Class, Method (0) | 2017.04.29 |