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 선언으로 정적 메소드로 선언되어 있다면 싱글톤을 보장받지 못 한다.

 

<학습 강의>

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B8%B0%EB%B3%B8%ED%8E%B8/dashboard