스프링은 기업용 온라인 서비스를 지원하기 위해서 탄생함. 대대분은 web으로 되어있음.
web의 특징 -> 여러 고객이 동시에 요청함.
고객 요청이 들어올때마다 객체가 계속 생성됨 -> 100번 요청이 들어오면 100개의 객체가 만들었다가 소멸됨 -> 메모리낭비가 심함.
//memberservice가 호출될 때마다 각각 다른 객체가 생성됨을 확인하는 test코드
public class SingleTonTest {
@Test
@DisplayName("스프링 없는 순수한 DI 컨테이너")
void pureContainer() {
AppConfig appConfig = new AppConfig();
//1. 조회: 호출 할 때마다 객체를 생성하는지
MemberService memberService1 = appConfig.memberService();
MemberService memberService2 = appConfig.memberService();
System.out.println("memberService1 = " + memberService1);
System.out.println("memberService2 = " + memberService2);
Assertions.assertThat(memberService1).isNotEqualTo(memberService2);
}
}
그래서 딱 하나만 생성해놓고, 생성된 인스턴스를 공유해서 쓰면 된다.
-> 그게 바로 싱글톤패턴!! : 클래스의 인스턴스가 딱 하나만 생성되는 것을 보장하는 패턴
public class SingletonService {
//자기 자신을 내부의 private으로 가지고 있는다.
//static 이라서 클래스level에서 딱 하나만 가지게 된다.
private static final SingletonService instance = new SingletonService();
//자기 자신을 조회하는 함수를 통해서만 조회가능
public static SingletonService getInstance() {
return instance;
}
//private 생성자를 만든다 -> 자기자신 밖에서는 new SingletonService를 생성하지 못하게 된다.
private SingletonService() {
}
public void logic() {
System.out.println("singleton Logic");
}
}
바깥에서 new SingletonService()를 만들려고 하면 오류가 난다.
오직 조회만을 사용해서 접근 가능하다
public static void main(String[] args){
SingletonService singletonService = SingletonService.getInstance();
singletonService.logic();
}
정말로 같은지 test코드를 작성해서 검증해보자
@Test
@DisplayName("싱글톤 테스트")
void singletonTest() {
//given
SingletonService singletonService1 = SingletonService.getInstance();
SingletonService singletonService2 = SingletonService.getInstance();
//when
//then
Assertions.assertThat(singletonService1).isSameAs(singletonService2);
}
기분 좋은 🟢 파란 불이 뜨는 것을 확인할 수 있다!!
이런 싱글톤 패턴도 문제점이 없지는 않다!!