public class SingletonTest {
@Test
@DisplayName("스프링 없는 순수한 DI 컨테이너")
void pureContainer(){
AppConfig appConfig = new AppConfig();
//1. 조회 : 호출할 때 마다 객체를 생성
MemberService memberService1 = appConfig.memberService();
MemberService memberService2 = appConfig.memberService();
//참조값이 다른 것을 확인
//계속 객체가 생성되어서 올라감 -> 많은 고객 요청 처리 어려움
System.out.println("memberService2 = " + memberService2);
System.out.println("memberService1 = " + memberService1);
// 같지 않아야 함
// 요청을 할 때마다 객체가 계~속 생성됨 해결 방안 => 싱글톤 패턴(객체 1개 생성 후 공유하도록 생성)
Assertions.assertThat(memberService1).isNotSameAs(memberService2);
}
}
우리가 만들었던 스프링 없는 순수한 DI 컨테이너인 AppConfig는 요청을 할 때 마다 객체를 새로 생성한다.
고객 트래픽이 초당 100이 나오면 초당 100개 객체가 생성되고 소멸된다! 메모리 낭비가 심하다.
해결방안은 해당 객체가 딱 1개만 생성되고, 공유하도록 설계하면 된다. -> 싱글톤 패턴
package hello.core.singleton;
public class SingletonService {
// 자기 자신을 외부에 private 으로 static 으로 가지고 있음 -> static 영역에 하나만 만들어서 올라감
private static final SingletonService instance = new SingletonService();
public static SingletonService getInstance(){
return instance;
}
private SingletonService(){
}
public void logic(){
System.out.println("싱글톤 객체 로직 호출");
}
}
// 호출 할 때
SingletonService singletonService1 = SingletonService.getInstance();
: 스프링 컨테이너는 싱글톤 패턴의 문제점을 해결하면서, 객체 인스턴스를 싱글톤(1개만 생성)으로관리한다. 지금까지 우리가 학습한 스프링 빈이 바로 싱글톤으로 관리되는 빈이다.


※ 참고: 스프링의 기본 빈 등록 방식은 싱글톤이지만, 싱글톤 방식만 지원하는 것은 아니다. 요청할 때 마다 새로운 객체를 생성해서 반환하는 기능도 제공한다.