Singleton?

Singleton?

Singleton이란 GoF가 소개한 디자인 패턴 중 하나다.


Singleton-Design-Pattern.jpg

Singleton이란 하나의 오브젝트를 만들고 이를 여러 Servlet에서 공유해서 사용하는 디자인 패턴이다.

Spring은 별다른 설정을 하지 않으면 내부에서 생성하는 빈 오브젝트를 모두 Singleton으로 만든다.

Spring이 주로 적용되는 대상이 자바 엔터프라이즈 기술을 사용하는 서버환경이기 때문. 서버로 요청이 들어오게되고 이를 처리하는 객체들을 요청이 들어올때마다 새로 생성하게되면 서버에 걸리는 부하가 크기 때문이다.

따라서 Singleton오브젝트를 하나 생성하고 이를 전역으로 사용한다.



Singleton의 구현

  • 주로 private로 선언해서 클래스 밖에서 오브젝트를 생성하지 못하도록 한다.
  • 생성된 싱글톤 오브젝트를 저장할 수 있는 static필드를 정의한다.
  • 자신의 Instance를 반환해줄 수 있는 static method를 만들고, 이 매서드가 처음 호출되는 시점에 단 한번만 오브젝트가 만들어지게 함.
  • 생성된 오브젝트는 static필드에 저장됨.
  • 한번 오브젝트가 만들어진 뒤에는 더 이상 생성하지 않고 static필드에 저장된 오브젝트를 리턴 (주로 getInstance()란 메소드를 이용하여 리턴받음).


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class UserDao {
    private static UserDao INSTANCE;

    private UserDao(ConnectionMaker connectionMaker){
        this.connectionMaker = connectionMaker;
    }

    public static synchronized UserDao getInstance(){
        if(INSTANCE == null){
            INSTANCE = new UserDao(??);
        }
        return INSTANCE;
    }
 ...
}



Singleton의 문제점

  • private 생성자를 가지기 때문에 상속할 수 없다.
    • Singleton은 생성자를 private로 제한하기 떄문에 다른 생성자가 없다면 상속하는 것이 불가능하다.
    • 이는 객체지향의 장점인 상속과 이를 이용한 다형성을 사용할 수 없음을 의미한다.
  • 테스트하기 힘들다.
    • 마찬가지로 만들어지는 방식이 제한적이기 때문에 Mock객체로 대체하기가 힘들다.
    • 테스트할 경우에는 직접 오브젝트를 만들어서 사용하는 방법뿐.
  • 서버환경에서는 Singleton이 하나만 만들어지는 것을 보장하지 못한다.
    • 서버에서 클래스로더를 어떻게 구성하고 있느냐에 따라서 Singleton임에도 여러 개의 오브젝트가 생성될 수 있다.
    • 여러 개의 JVM에 분산돼서 설치가 되는 경우에도 독립적으로 오브젝트가 생기게 된다.
  • Singleton의 사용은 전역상태를 만들 수 있기 때문에 바람직하지 못하다.
    • 클라이언트가 정해져있지 않고 static method로 접근할 수 있기 때문에 어디서든지 사용될 수 있다.
    • 전역상태는 객체지향 프로그래밍에서는 권장되지 않는 모델.
따라서 Stateless(무상태)방식으로 만들어져야 함!



Singleton Registry

이러한 문제점이 있기 때문에 Spring은 직접 Singleton을 생성하고, 관리하고 공급하는 컨테이너인 Singleton Registry를 제공한다.