스프링

싱글톤 패턴(Singleton)

쿠쿠s 2022. 5. 26. 22:36

 

정의

  • 객체의 인스턴스가 오로지 한개만 생성되도록 설계하는 것
  • 클래스의 인스턴스화를 하나의 객체로 제한

 

 

왜 쓰는지??

  • Singleton은 고유한 리소스를 캡슐화하여 애플리케이션 전체에서 쉽게 사용할 수 있도록 함
  • 캘린더, 로깅 등에 사용 됨 why? => 오로지 한개만 필요하기 때문에
 

 

기타 장점

  • 인터페이스를 구현 가능
  • 지연 로드 가능

 

단점

  1. 전역 상태는 코드의 결합을 증가시키기 때문에 리팩토링하기가 어려워 진다. 클래스가 싱글톤의 구체적인 구현에 의존하게 된다.
    • → IoC/ DI 컨테이너를 사용하여 객체를 요청하는 하는 것으로 바꿔야 한다.
  2. 단위 테스트가 어려워짐
    • → 생성자를 통해 동적으로 객체를 주입할 수 없어 이런 경우는 필요한 객체를 직접 만들어서 사용해야 하기 때문에 테스트용 객체로 대체하기가 힘듬
  3. 단일 책임의 원칙은 모든 클래스가 하나의 책임만을 가져야 한다는 원칙, 싱글톤 클래스는 클래스의 작업을 처리하는 역할 뿐 아니라 자신의 인스턴스에 대한 접근을 관리하는 역할에 대해서도 책임을 진다.
  4. 싱글톤 클래스는 생성자가 private으로 지정되기 때문에 상속이 불가능
  5. 생성자 문제 뿐만 아니라, 싱글톤 클래스는 static 변수를 바탕으로 하기 때문에 모든 서브클래스들이 그 변수를 공유하게 된다. 이를 해결하기 위해서는 '레지스트리'를 구현해두어야 한다.
  6. 멀티 스레드를 적용하면 여러 스레드에서 한개의 싱글톤 클래스에 접근하게 된다.
    • 이는 동기화 문제를 발생시킬 수 있으니 volatile 키워드를 통해 Double Checking Locking을 적용하거나 getInstance() 메소드에 synchronized 키워드를 적용하여 동기화 해야한다. 그런데 synchronized 키워드를 적용하면 스레드에서 getInstance() 할 떄마다 속도가 느려지는 문제가 발생

 

왜 스프링은 싱글톤으로 빈을 만들까?

  • 스프링이 주로 적용되는 대상이 자바 엔터프라이즈 기술을 사용하는 서버환경이기 때문
  • 만약 매번 클라이언트의 요청이 올 때마다 각 로직을 담당하는 빈 객체를 새로 만들면? → 서버의 부하가 생김
  • 서비스가 stateless 면 멀티 스레드로부터 안전하고 동시 요청 수에 관계없이 확장할 수 있으므로 하나의 객체만 있으면 된다.
  • 스프링이 직접 싱글톤을 생성하고, 관리하고, 공급하기 때문에 평범한 자바 클래스를 싱글톤으로 활용가능하게 한다. → 싱글톤 레지스트리

*엔터프라이즈 시스템: 서버에서 동작하며 기업과 조직의 업무를 처리해주는 시스템. 많은 사용자들의 요청을 동시 처리 해야하므로 서버지원을 효율적으로 공유하고 분배해서 사용할 수 있어야 한다. 또한 중요한 기업 핵심정보 다루기때문에 보안,안정성,확장성 이 요구된다

 

 

자바 싱글톤과 스프링 싱글톤의 차이?

자바 싱글톤패턴은 미리 메모리에 올라가든, lazy하게 올라가든 결국 메모리에 올라가면 애플리케이션이 종료될 때 까지 메모리를 차지하기 때문에 메모리 낭비가 있고, 이것을 스프링 컨테이너가 빈을 생성하고 의 생명주기까지 관리하기 때문에 메모리에 계속 올라가있지 않는다.

 

 

*주의

  • 객체 인스턴스를 하나만 생성해서 공유하는 싱글톤 방식은 여러 클라이언트가 하나의 같은 객체 인스턴스를 공유하기 때문에 상태를 유지하게 설계하면 안된다.
  • 특정 클라이언트에 의존적인 필드가 있으면 안된다.
  • 특정 클라이언트가 값을 변경할 수 있는 필드가 있으면 안된다.
  • 가급적 읽기만 가능해야 한다.
  • 스프링빈은 항상 무상태로 설계하자

 

 

 

 

https://www.davidtanzer.net/david's blog/2016/03/14/6-reasons-why-you-should-avoid-singletons.html

https://www.inflearn.com/course/스프링-mvc-1/dashboard

'스프링' 카테고리의 다른 글

XSS 와 CSRF  (0) 2022.06.05
서블릿(Servlet)  (0) 2022.05.31
REST ? RESTful ? REST API?  (0) 2022.05.26
관심사의 분리(Seperation Of Concern)  (2) 2022.05.18
스프링(Spring)은 왜 사용할까?  (0) 2022.03.25