본문 바로가기
Web/Spring

[스프링구조] 스프링에서의 싱글톤

by Geunny 2022. 5. 18.
반응형

싱글톤 패턴은 디자인 패턴중에서 가장 친근하고 쉽게 접할수 있는 패턴이다.

 

그리고 스프링을 배우게 된다면

스프링에서는 스프링 빈객체들을 싱글톤으로 관리한다고 배운다.

 

하지만 일반적인 싱글톤 디자인패턴과 스프링에서 사용되는 싱글톤은

개념은 같으나 다르게 동작하게 된다.

 

아래 글은 일반적인 싱글톤 방식과

실제 스프링에서 싱글톤이

어떤 방식으로 진행되는지 정리해보려 한다.

 

 

싱글톤 패턴 (개념)

먼저 싱글톤 패턴의 기본 개념을 살펴보자

In software engineering, the singleton pattern is a software design pattern that restricts the instantiation of a class to one "single" instance. This is useful when exactly one object is needed to coordinate actions across the system.

wiki의 등록된 글에 따르면 싱글톤은 하나의 클래스의 인스턴스화를 1개로 제한하는 패턴으로

메모리 어디에서 해당 클래스를 불러와도 같은 메모리 주소에 존재하는 인스턴스를 사용하는 패턴이다.

 

자바에서 싱글톤 객체를 구현할땐 주로 아래와 같은 형식으로 구현한다.

 

class Singleton{
    private static Singleton INSTANCE = new Singleton();
    
    private Singleton(){
    }
    
    public static Singleton getInstance(){
        return INSTANCE;
    }
}

 

위 Singleton 클래스는 다른 외부에서는 new연산자를 이용하여 생성할수 없고,

getInstance() 메서드를 이용하여 클래스 내부 INSTANCE 객체를 불러와 사용할 수 있다.

 

이렇게 구현되면 동일한 JVM 안에서 해당 INSTANCE를 어디에서 가져와도 동일한 객체를 가져오게 된다.

 

public class DesignPatternMain {
    public static void main(String[] args) {

        Singleton s1 = Singleton.getINSTANCE();
        Singleton s2 = Singleton.getINSTANCE();

        System.out.println(s1);
        System.out.println(s2);

        System.out.println(s1==s2);

    }
}

 

스프링에서 싱글톤으로 빈을 만드는 이유

스프링을 사용하는 이유중 하나는 서버환경에서

엔터프라이즈 시스템을 위해 사용된다.

엔터프라이즈 환경에서 클라이언트의 요청이 올때마다

해당 로직을 담당하는 오브젝트를 새로 만들어서 사용하게 되면

수십만개의 요청이 올때 요청 갯수만큼 오브젝트가 생성되어 서버가 감당하기 힘들다.

 

그로인해 서블릿 자바 엔터프라이즈 환경떄 부터

서비스 오브젝트 개념이 사용되어 왔고

대부분 멀티스레드 환경에서 싱글톤으로 동작하게 된다.

 

이렇게 애플리케이션에서 제한된 수(1개) 로 오브젝트로 만들어

사용하는 방식이 서버환경에서 권장된다.

 

 

하지만 이러한 싱글톤 패턴의 구현에는 다음과 같은 문제점이 존재한다.

 

1. private 생성자를 갖고 있기에 해당 클래스는 상속받을 수 없다.

 

싱글톤패턴은 생성자를 private으로 제한하여

오직 해당 클래스에서만 인스턴스를 생성할 수 있다.

또한 해당 클래스는 다른 생성자가 없어 상속이 불가능 하다.

(상속받은 객체는 생성자를 만들수 없기 떄문)

객체의 상속이 불가능 하다면 애플리케이션 로직을 담은 서비스의 경우

객체지향적인 설계의 장점을 이용하기 어려워진다.

이로인해 다형성을 적용할 수 없는 문제점이 생기게 된다.

 

2. 싱글톤은 테스트하기 힘들다.

 

싱글톤으로 만들경우 테스트코드를 작성하기 어렵거나 아예 테스트가 불가능하다.

싱글톤은 만들어지는 방식이 제한적이기 때문에 목 오브젝트로 대체도 불가능하다.

또한 스프링의 특징중 DI를 이용한 객체주입도 사용이 불가능하다.

 

3. 서버환경에서는 싱글톤이 하나만 만들어지는 것을 보장하지 못한다.

 

서버에서 클래스 로더를 어떻게 구성하느냐에 따라

싱글톤 임에도 하나이상의 오브젝트가 만들어 질 수 있다.

여러 개의 JVM에 분산돼서 설치 되는 경우

각각 독립적으로 오브젝트가 생성되기 때문에

싱글톤으로서의 가치가 떨어지게 된다.

 

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

 

싱글톤은 사용하는 클라이언트가 정해져 있지 않다.

언제 어디서든 스테틱 메서드를 이용하여 쉽게 접근할 수 있기 때문에

애플리케이션 어디서든 사용될 수 있고,

자연스럽게 전역상태(global state)로 사용되기 쉽다.

이는 OOP(객체지향프로그래밍)에서 권장되지 않는 프로그래밍 모델이다.

 

 

 

스프링 싱글톤 레시즈스트리

이러한 문제점 때문에 스프링에서는

싱글톤 형태의 오브젝트를

생성,관리하는 기능을 제공해준다.

 

스프링 컨테이너는 싱글톤을

생성하고,관리하고, 공급하는

싱글톤 관리 컨테이너(싱글톤 레시즈트리)의 역할을 한다.

 

스프링에서의 싱글톤은

private 생성자와 static method 를 쓰는방식의

자바 싱글톤과는 달리

평범한 자바 클래스 처럼 사용할수 있다.

 

이로인해 테스트 환경에서도 해당 오브젝트를 생성할 수 있고,

다른 오브젝트를 주입 받을 수 있게 된다.

 

또한 스프링에서는 일반적인 오브젝트 생성방식이 아닌

프록시 빈 또는 자바 리플랙션을 이용한 방식으로 객체 생성하기 때문에

일반적인 자바 싱글톤 오브젝트와는 동작은 같으나

다른 방식으로 생성됨을 인지하고 있어야 한다.

 

출처 : 토비의 스프링 3.1

댓글