본문 바로가기

Spring/Spring

[Spring] 싱글톤 패턴과 싱글톤 컨테이너

반응형

1. 싱글톤 패턴

  • 클래스의 인스턴스가 딱 1개만 생성되는 것을 보장하는 디자인 패턴

 

싱글톤 패턴을 사용하는 이유

우리가 웹, 앱을 사용하다 보면 클라이언트가 수많은 요청들을 하는 것을 볼 수 있다.

그럴 때마다 서버 입장에서는 요청이 들어올 때마다 객체를 생성하면 메모리 낭비가 심하게 되므로

이를 해결할 방법이 필요했는데 이때 사용하는 것이 싱글톤 패턴이다.

 

public class SingletonService {

    private static final SingletonService instance = new SingletonService(); 

    public static SingletonService getInstance() {
        return instance;
    }

    private SingletonService() {

    }

    public void logic() {
        System.out.println("싱글톤 객체 로직 호출");
    }
}

 

싱글톤을 구현한 위 코드를 보면

SingletonService 자기 자신 객체를  다른 곳에서 참조하거나 변경할 수 없도록 private, static, final을 이용하여 선언한다.

그리고 getInstance 메서드는 바로 위의 자기 자신 객체 instance를 반환하는 것을 볼 수 있다.

아래의 private SingletonService() 생성자는 자신의 생성자를 private으로 해놨기 때문에 다른 곳에서 SingletonService 객체를 생성하지 못 하도록 막아준다.

 

싱글톤 패턴이 잘 적용되었는지 테스트를 하기 위해 singletonTest 클래스를 만들고 SingletonService 객체를 꺼내야 하는데 위에서 생성자를 private으로 해놓았기 때문에 인스턴스를 꺼내려면 getInstance로 꺼내야 한다. 

그러면 아래와 같이 동일한 인스턴스가 출력된 것을 볼 수 있다.

public class singletonTest {


   @Test
    @DisplayName("싱글톤 패턴을 적용한 객체 사용")
    void singletonServiceTest() {
       SingletonService singletonService1 = SingletonService.getInstance();
       SingletonService singletonService2 = SingletonService.getInstance();

       System.out.println("singletonService1 = " + singletonService1);
       System.out.println("singletonService2 = " + singletonService2);

   }
}

 

 

 

싱글톤 패턴은 이미 만들어진 객체를 공유해서 불필요한 메모리를 줄여주고 효율성을 높일 수 있지만 상당히 많은 단점들이 존재한다.

싱글톤 패턴의 단점

  • 싱글톤 패턴 구현하는 코드
  • 클라이언트가 구체 클래스에 의존 - DIP 위반
  • 테스트하기 어렵다
  • 내부 속성 변경하거나 초기화 어렵다

 

위의 싱글톤 패턴의 단점들을 보완하기 위해서 나온 것이 싱글톤 컨테이너이다.


 

2. 싱글톤 컨테이너

스프링 컨테이너는 싱글턴 패턴을 적용하지 않아도 객체 인스턴스를 싱글톤으로 관리해준다.

즉 스프링 컨테이너가 싱글톤 컨테이너 역할을 하며 우린 스프링 컨테이너 덕분에 싱글톤 패턴의 단점들을

겪지 않으며 객체를 싱글톤으로 유지할 수 있다.

 

 

   @Test
    @DisplayName("스프링 컨테이너와 싱글톤")
    void springContainer() {
       ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);

       MemberService memberService1 = ac.getBean("memberService", MemberService.class);
       MemberService memberService2= ac.getBean("memberService", MemberService.class);

       System.out.println("memberService1 = " + memberService1);
       System.out.println("memberService2 = " + memberService2);
       
   }
}

스프링 컨테이너 (ApplicationContext)를 이용하여 싱글톤을 구현한 코드이다.

 

 

동일한 객체가 반환된 것을 볼 수 있다.

 

 

출처 :  인프런 - 스프링 핵심 원리 (기본편)

 

반응형