Spring 시리즈는 혼자 공부하며 기록으로 남기고, 만약 잘못 학습 한 지식이 있다면 공유하며 피드백을 받고자 작성합니다.
스프링에 대해 깊게 공부해보고자 인프런의 김영한 강사님께서 강의를 진행하시는 (스프링 핵심 원리 - 기본편) 강의를 수강하며 정리하는 글입니다.
혹여나 글을 읽으시며 잘못 설명된 부분이 있다면 지적 부탁드리겠습니다.
스프링 컨테이너는 싱글톤 패턴의 문제점을 해결하면서 객체 인스턴스를 싱글톤으로 관리한다.
지금까지 계속 학습한 스프링 빈이 싱글톤 방식으로 동작한다.
public class SingletonTest {
@Test
@DisplayName("스프링 컨테이너와 싱글톤")
void springContainer() {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
// 1. 조회 : 호출할 때마다 객체를 생성
MemberService memberService1 = ac.getBean("memberService", MemberService.class);
// 2. 조회 : 호출할 때마다 객체를 생성
MemberService memberService2 = ac.getBean("memberService", MemberService.class);
//참조 값이 다른 것을 확인
System.out.println("memberService1 = " + memberService1);
System.out.println("memberService2 = " + memberService2);
//memberService != memberService2
assertThat(memberService1).isSameAs(memberService2);
}
}
getBean()메서드를 사용하여 컨테이너에 있는 객체 인스턴스를 꺼내온다.


참고 : 기본 빈 등록은 싱글톤 방식이지만, 요청할때마다 새로운 객체를 생성해서 반환하는 방법도 존재한다.
문제 코드 예시
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
public StatefulService statefulService() {
return new StatefulService();
}
}
}
StatefulService.class를 각각 statefulService1, statefulService2에 할당한다.무상태(stateless)로 설계하여야한다.