본문 바로가기

SPRING

[토비] Spring 싱글톤 패턴의 이야기

스프링은 BeanFactory를 통해 생성되는 Bean을 출력해보면

같은 주소 값이 나온다.

이 얘기는 하나의 객체를 각각의 변수도 같은 주소를 보고 있다는 얘기가 된다.

곧 '스프링은 싱글톤 패턴으로 Bean을 관리한다'가 되겠다.

 

이 스프링에서 관리되는 싱글톤 패턴은 우리가 알고 있는 싱글톤 패턴이랑 동일하지만 구현 방법은 완전히 다르다.

흔히 싱글톤 패턴은 이렇게 구현된다.

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;

}

}

나도 업무에서 자주 보고 흔히 사용하던 싱글톤 패턴에는 이런 문제가 있었다.

 

1. private 생성자를 갖고 있기 때문에 상속할 수 없다.

싱글톤 패턴은 생성자를 prviate로 한다. 오로지 자기 자신만이 오브젝트에 접근 가능하도록 제한하는 것이다. private 때문에 상속이 불가능하다는 것이며 이는 객체 지향의 장점인 다형성과 객체지향의 순수한 그 원리를 이용 할 수 없게 된다. 또한 static 필드와 method를 사용한다는 것도 같은 이야기일 수도 있다.

2. 테스트 하기 힘들다.

private이기 때문에 만들어지는 방식이 제한적인데다가 생성과정에서 다이나믹하게 주입할수도 없다. 직접 생성해서 사용해야하며 이런 경우 테스트용 클래스로 대체하기 어렵다.

3. 서버환경에서 싱글톤이 과연 하나만 만들어지는가 ?

서버에서 클래스 로더를 어떻게 구성하느냐에 따라 여러개의 싱글톤 클래스가 생성될 수 있다. 따라서 자바 언어를 이용한 싱글톤 패턴 기법은 서버환경에서 꼭 보장 된다고 볼 수 없다. 분산된 JVM환경에서도 각각 환경에서 싱글톤 객체는 개별로 존재하기 때문이다.

4. 싱글톤의 사용은 전역상태를 만들 수 있기 때문에 바람직하지 못하다.

기본적으로 static 메서드와 static 변수로 인해서 클래스는 전역상태가 된다. 이 전역상태라는 것은 프로그램 내부에서 수정이나 사용될 수 있다는 것을 의미한다. 객체 지향에서는 이 전역상태를 권장하지 않는 모델이며 차라리 static 필드와 method로만 구성된 클래스를 사용하는 편이 낫다고 한다.

자바에서의 싱글톤은 이런 문제를 안고 있다.

그래서 스프링에서는 싱글톤 레지스트리를 이용해서 마치 private와 static가 아닌 일반 클래스도 싱글톤 처럼 관리해주는 방식을 제공한다.

토비 스프링에서