스프링 싱클톤 패턴

changho Youn·2023년 11월 25일

싱클톤 패턴

package singleton;

import com.changddao.fall_in_spring.AppConfig;
import com.changddao.fall_in_spring.member.MemberService;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

public class SingletonTest {
    @Test
    @DisplayName("스프링 없는 순수한 DI 컨테이너")
    void pureContainer() {
        //given
        AppConfig appConfig = new AppConfig();
        //when
        //1. 조회: 호출할 때 마다 객체를 생성
        MemberService memberService1 = appConfig.memberService();
        //2. 조회: 호출할 때 마다 객체를 생성
        MemberService memberService2 = appConfig.memberService();
        //that
        System.out.println("memberService1 = " + memberService1);
        System.out.println("memberService2 = " + memberService2);
        //memberService1 != memberService2
        Assertions.assertThat(memberService1).isNotSameAs(memberService2);
    }
}

  • 스프링이 없는 순수한 DI 컨테이너인 AppConfig는 요청을 할 때 마다 객체를 새로 생성한다.
  • 고객 트래픽이 초당 100이 나오면 초당 100개 객체가 생성되고 소멸된다!
    -> 메모리 낭비가 심하다.
  • 해결방안은 해당 객체가 딱 1개만 생성되고, 공유하도록 설계하면 된다. -> 싱글톤 패턴

그래서 싱글톤 패턴 어떻게 사용하는데?

  • 클래스의 인스턴스가 딱 1개만 생성되는 것을 보장하는 디자인 패턴이다.
  • 객체 인스턴스를 2개 이상 생성하지 못하도록 막아야 한다.
    -> private 생성자를 사용해서 외부에서 임의로 new 키워드를 사용하
    지 못하도록 막아야 한다.

package singleton;

public class SingletonService {
    private static final SingletonService instance = new SingletonService();

    public static SingletonService getInstance(){
        return instance;
    }
    private SingletonService(){

    }
}
  • SingletonService의 생성자를 private으로 선언하여 외부에서 접근하지 못하도록 막고, 내부에서 static으로 선언된 getInstance를 이용하여 객체를 호출한다.

너무나도 당연하겠지만 SingletonService에서 getInstance메소드를 호출한 객체가 같은지 비교해보자

   @Test
    @DisplayName("싱글톤 패턴을 적용한 객체 사용")
    void singletonService() {
        //given
        //오류 발생
        /*SingletonService singletonService = new SingletonService(); //*/
        //when
        SingletonService service1 = SingletonService.getInstance(); // 이런식으로 싱글톤 사용
        SingletonService service2 = SingletonService.getInstance(); // 이런식으로 싱글톤 사용
        // that

        Assertions.assertThat(service1).isEqualTo(service2);
    }

테스트결과

-> 싱글톤 패턴을 이용하면 불필요한 자원 낭비를 막을 수 있다. 물론 garbage collection이 많은 객체들이 쌓였을 때, 잘 처리를 해주겠지만 사전에 불필요한 객체 생성을 막을 수 있기에 싱글톤 패턴을 이용하는 것은 매우 합리적이다.

  
profile
BackEnd Developer ChangDDAO입니다.🐌

0개의 댓글