프로그래밍/Spring
[ Spring ] DI 컨테이너 싱글톤 방식의 문제점
Yanoo
2022. 2. 5. 01:30
728x90
반응형
<인프런의 김영한님의 강의를 보고 정리한 내용입니다>
싱글톤 방식은 여러 클라이언트가 하나의 같은 인스턴스를 공유하기 때문에 상태를 유지하게(stateful)하게 설명하면 안된다. 이유를 보면,
public class StatefulService {
private int price; //상태를 유지하는 필드
public void order(String name, int price) {
System.out.println("name = " + name + " price = " + price);
this.price = price; //여기가 문제!
}
public int getPrice() {
return price;
}
}
이렇게 작성하고
class StatefulServiceTest {
@Test
void statefulServiceSingleton() {
ApplicationContext ac = new AnnotationConfigApplicationContext(TestConfig.class);
StatefulService statefulService1 = ac.getBean(StatefulService.class);
StatefulService statefulService2 = ac.getBean(StatefulService.class);
//ThreadA: A사용자 10000원 주문
statefulService1.order("userA", 10000);
//ThreadB: B사용자 20000원 주문
statefulService2.order("userB", 20000);
//ThreadA: 사용자A 주문 금액 조회
int price = statefulService1.getPrice();
System.out.println("price = " + price);
Assertions.assertThat(statefulService1.getPrice()).isEqualTo(20000);
}
static class TestConfig {
@Bean StatefulService statefulService() {
return new StatefulService();
}
}
}
테스트 코드를 작성했을 때, 내가 원하는 사용자A의 price는 10000이지만 이 코드의 결과를 보면 20000원이 나오게 된다. 이러면 큰 장애가 발생한 것이다.
그래서 싱글톤인 상황이므로 stateless하게 코드를 작성해야 한다.
public class StatefulService {
private int price; //상태를 유지하는 필드
public int order(String name, int price) {
System.out.println("name = " + name + " price = " + price);
// this.price = price; //여기가 문제!
return price;
}
}
class StatefulServiceTest {
@Test
void statefulServiceSingleton() {
ApplicationContext ac = new AnnotationConfigApplicationContext(TestConfig.class);
StatefulService statefulService1 = ac.getBean(StatefulService.class);
StatefulService statefulService2 = ac.getBean(StatefulService.class);
//ThreadA: A사용자 10000원 주문
int userAPrice = statefulService1.order("userA", 10000);
//ThreadB: B사용자 20000원 주문
int userBPrice = statefulService2.order("userB", 20000);
//ThreadA: 사용자A 주문 금액 조회
System.out.println("userAPrice = " + userAPrice);
}
static class TestConfig {
@Bean StatefulService statefulService() {
return new StatefulService();
}
}
}
이렇게 수정해야 한다.
728x90
반응형