Development/Spring
웹 애플리케이션과 싱글톤
우봉수
2023. 3. 15. 17:49
자바 예시 코드
public class SingletonService {
private static final SingletonService instance = new SingletonService();
public static SingletonService getInstance(){
return instance;
}
private SingletonService(){
}
}
필요성
- 웹 애플리케이션은 동시에 많은 사용자가 이용한다. 이때 각각의 경우마다 새로운 인스턴스를 생성하는 건 비효율적이고 문제가 있다.
- 따라서 싱글톤 기법으로 작성해둬야 할 필요가 있다.
문제점
- 싱글톤 패턴을 구현하는 코드 자체가 많이 들어간다.
- 의존관계상 클라이언트가 구체 클래스에 의존한다 → DIP를 위반한다.
- 테스트를 하기 어렵다.
- 내부 속성을 변경하거나 초기화 하기 어렵다.
- private 생성자로 자식 클래스를 만들기 어렵다.
- 결론적으로 유연성이 떨어진다.
- 안티패턴으로 불리기도 한다.
Spring에서의 싱글톤
- 스프링 컨테이너를 사용하면 Bean에 등록된 모든 클래스를 싱글톤 패턴으로 관리해 주기 때문에 일일이 싱글톤으로 선언 할 필요가 없다.
스프링 컨테이너
- 스프링 컨테이너는 싱글톤 패턴의 문제점을 해결하면서, Bean 저장소에 등록된 객체 인스턴스를 싱글톤으로 관리한다.
- 싱글톤 컨테이너의 역활을 한다. (싱글톤 레지스터 기능)
- 싱글톤 패턴을 위한 지저분한 코드가 들어가지 않아도 된다.
- DIP, OCP, 테스트, private 생성자로 부터 자유롭게 싱글톤을 사용 할 수가 있다.
- @Configuration 어노테이션으로 등록된 클래스 그대로 등록 되는 것이 아니라 CGLIB라는 바이트코드 조작 라이브러리가 해당 클래스를 상속받은 임의의 다른 클래스를 만들고 그 다른 클래스를 Spring Bean으로 등록한다
- 주의: @Bean만 사용해도 스프링 빈으로 등록되지만, 싱글톤을 보장하지 않는다 따라서 꼭 @Configuration 어노테이션을 사용해주어야 한다.
싱글톤 방식의 주의점
- 객체 인스턴스 하나만 생성해서 공유하는 방식은 여러 클라이언트가 같은 객체 인스턴스를 공유하기 때문에 싱글톤 객체는 상태를 유지(statefull)하게 설계하면 안된다.
- 무상태(stateless)로 설계해야 한다.
- 특정 클라이언트에 의존적인 필드가 있으면 안된다.
- 특정 클라이언트가 값을 변경할 수 있는 필드가 있으면 안된다.
- 가급적 읽기만 가능하도록 해야 한다.
- 필드 대신에 자바에서 공유되지 않는, 지역변수, 파라미터 등을 사용해야 한다.
- 스프링 빈의 필드에 공유 값을 설정하면 정말 큰 장애가 발생할 수 있다.
- @Configuration과 @Bean의 조합으로 싱글톤을 보장하는 경우는 정적이지 않은 메서드일 때이다 즉 static 선언으로 정적 메소드로 선언되어 있다면 싱글톤을 보장받지 못 한다.
<학습 강의>