정의
- 객체의 인스턴스가 오로지 한개만 생성되도록 설계하는 것
- 클래스의 인스턴스화를 하나의 객체로 제한
왜 쓰는지??
- Singleton은 고유한 리소스를 캡슐화하여 애플리케이션 전체에서 쉽게 사용할 수 있도록 함
- 캘린더, 로깅 등에 사용 됨 why? => 오로지 한개만 필요하기 때문에
기타 장점
- 인터페이스를 구현 가능
- 지연 로드 가능
단점
- 전역 상태는 코드의 결합을 증가시키기 때문에 리팩토링하기가 어려워 진다. 클래스가 싱글톤의 구체적인 구현에 의존하게 된다.
- → IoC/ DI 컨테이너를 사용하여 객체를 요청하는 하는 것으로 바꿔야 한다.
- 단위 테스트가 어려워짐
- → 생성자를 통해 동적으로 객체를 주입할 수 없어 이런 경우는 필요한 객체를 직접 만들어서 사용해야 하기 때문에 테스트용 객체로 대체하기가 힘듬
- 단일 책임의 원칙은 모든 클래스가 하나의 책임만을 가져야 한다는 원칙, 싱글톤 클래스는 클래스의 작업을 처리하는 역할 뿐 아니라 자신의 인스턴스에 대한 접근을 관리하는 역할에 대해서도 책임을 진다.
- 싱글톤 클래스는 생성자가 private으로 지정되기 때문에 상속이 불가능
- 생성자 문제 뿐만 아니라, 싱글톤 클래스는 static 변수를 바탕으로 하기 때문에 모든 서브클래스들이 그 변수를 공유하게 된다. 이를 해결하기 위해서는 '레지스트리'를 구현해두어야 한다.
- 멀티 스레드를 적용하면 여러 스레드에서 한개의 싱글톤 클래스에 접근하게 된다.
- 이는 동기화 문제를 발생시킬 수 있으니 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
'스프링' 카테고리의 다른 글
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 |