Spring 의 Bean 들은 대게 Singleton 패턴으로 정의되며 Application Context 에서 관리되는 형태로 개발자는 사용하게 된다.


그렇게 때문에 상당수의 개발자들이 Spring 의 각 Bean 들은 Thread Safety 가 보장된 안전한 Bean Object 이며 Spring 은 해당 동시성 문제에서 자유롭다고 여기는 경향이 있다.


하지만 정확히 Spring Bean 들은 Thread 의 Safety 와 무관하다. 


Spring Container 는 Object 들 각각에 대한 Life cycle 을 갖고 있으며 Container 내에서 하나만 존재하도록 보장하지만 그것이 Thread-Safe 를 말하는 것은 결코 아니며, Spring framework 는 오히려 이 책임을 개발자에게 맡긴다.


만약 Non-Thread-Safe Object 가 Injection 된다면 해당 객체는 쓰레드에 안전하지 않으며 개발자가 직접 핸들링해주어야 한다.


그렇다면 Bean 에 대해 어떤 방식으로 Thread Safety 를 부여할 수 있을까?


(1) Builder Pattern 의 사용

  간단하면서도 Tricky 한 방식으로 Builder Pattern 을 사용하면 좋다.

 Builder 패턴을 이용하면 객체의 Setter 를 정의하지 않은 상태에서 생성자만으로 객체의 Mutation 을 관리할 수 있으며, Spring 의 Bean 들은 Container 에 의해 life cycle 관리가 위임된다.

 따라서 Builder Pattern 을 통해 Set 을 관리하면 간단하면서도 명확히 Thread Safe 를 구현할 수 있다.


(2) Stateless Bean

  Bean 을 상태값과 무관하게 동작할 수 있는 Bean 으로 설계하는 것이다. 

  Bean 이 특정 상태를 나타내는 변수를 계속 메모리에 들고 상주하는 형태가 아닌, 가장 단순한 형태의 도메인 모델로 사용이 추천된다.


(3) Lock the beans

  가장 최후의 수단으로 여겨야 하는 방법으로 Bean 에 대해 Thread Safe 하게 설계를 하는 것이다. Spring 은 Lower level Library 들을 통해 Bean 단위의 Lock 을 지원하고 있으며 이를 통해 병렬처리에 있어서 동시성 문제의 해결이 필요하다.


물론 실제로 Safe 하지 않은 상황을 고려해야할 경우는 많지 않지만, 각기 다른 Request 를 공통으로 분류해야한다거나, 내부에서 Internal Thread 를 구동하는 경우에는 반드시 신경써보자.



+ Recent posts