본문 바로가기
FrameWork/Spring

웹 애플리케이션과 싱글톤

by titlejjk 2023. 7. 19.

스프링은 태생이 기업용 온라인 서비스 기술을 지원하기 위해 생겼다.

물론 온라인만 처리하는 것이 아닌 여러종류의 애플리케이션이 있다.

대부분의 스프링 애플리케이션은 웹 애플리케이션도 있고 웹이 아닌 애플리케이션 개발도 얼마든지 할 수 있다.

웹 애플리케이션은 보통 여러 고객이 동시에 요청을 한다.

 

클라이언트(고객)들의 여러번 요청하면 웹 애플리케이션은 요청이 올때마다 객체를 만들어야 한다.

 

Appconfig를 호출할 때 마다 새로운 객체가 생성이 되는데, 위에말처럼 고객들을 대상으로 하는 온라인 서비스이기 때문에 요청하는 고객들이 많아질 수록 엄청난 양의 객체가 생성될 수 있다.

순수한 DI컨테이너인 AppConfig는 요청을 할 때마다 객체를 새로 생성한다.

고객 트래픽이 초당 100개가 나오면 초당 100개의 객체가 생성/소멸이 된다. 이 말은 즉 메모리낭비가 굉장히 심해지는 경우이며, 이를 해결 하기 위해서는 해당 객체가 딱 1개만 생성되고, 생성된 객체를 공유하도록 설계하면 된다. 이렇게 나온 것이 싱글톤 패턴이다.

 

싱글톤 패턴이란?

클래스의 인스턴스가 딱 1개만 생성되는 것을 보장하는 디자인 패턴이다. 한 자바서버안에서는 단 한개의 객체 인스턴스만 생기게 하는 것 이다. 객체 인스턴스를 2개 이상이 생성되지 않도록 해주면 된다.

 

package hello.core.singleton;

public class SingletonService {

    //1. static 영역에 객체를 딱 1개만 생성한다.
    private static final SingletonService instance = new SingletonService();

    //2. public으로 열어서 객체 인스턴스가 필요하면 이 static 메서드를 통해 조회하도록 허용한다.
    public static  SingletonService getInstance(){
        return instance;
    }

    //3. 생성자를 private으로 선언해서 외부에서 new키워드를 사용한 객체 생성을 못하게 막는다.
    private SingletonService(){

    }

    public void logic(){
        System.out.println("싱글톤 객체 로직 호출");
    }
}

 

먼저 private로

static영역에 SingletonService를 올려준다. 이렇게 되면 객체를 단 1개만 생성하게 된다.

private static final SingletonService instance = new SingletonService();

이를 public으로 열어서 객체 인스턴스가 필요하면 이 static 메서드를 통해 조회하도록 한다.

//2. public으로 열어서 객체 인스턴스가 필요하면 이 static 메서드를 통해 조회하도록 허용한다.
    public static  SingletonService getInstance(){
        return instance;
    }

그리고 생성자를 private으로 선언하여 외부에서 new로 객체를 생성하지 못하게 막도록 해준다.

 //3. 생성자를 private으로 선언해서 외부에서 new키워드를 사용한 객체 생성을 못하게 막는다.
    private SingletonService(){

    }

싱글톤으로 만들었기에 new를 이용해 호출하는 것 조차 안된다.

 

getInstance()로 호출했을 때 객체의 값이 같은 것을 확인 할 수 있다!

하지만 이런 싱글톤자체에도 단점이 존재한다.

 

  • 싱글톤 패턴을 구현하는 코드 자체가 많아 진다.
package hello.core.singleton;

public class SingletonService {

    //1. static 영역에 객체를 딱 1개만 생성한다.
    private static final SingletonService instance = new SingletonService();

    //2. public으로 열어서 객체 인스턴스가 필요하면 이 static 메서드를 통해 조회하도록 허용한다.
    public static  SingletonService getInstance(){
        return instance;
    }

    //3. 생성자를 private으로 선언해서 외부에서 new키워드를 사용한 객체 생성을 못하게 막는다.
    private SingletonService(){

    }

 

  • 의존관계상 클라이언트가 구체 클래스에 의존해야한다.
    .Instance()메서드를 사용함으로써 구체 클래스에 의존해야 하므로 DIP를 위반하게 된다.
  • 클라이언트가 구체 클래스에 의존해서 OCP원칙을 위반할 가능성이 높다.

  • 테스트가 하기 어렵다.
    유연하게 테스트하기 힘듬
  • 내부속성을 변경하거나 초기화하기 어렵다.
  • private를 사용하기 때문에 자식 클래스를 만들기 어렵다.
  • 유연성이 떨어짐
  • 안티패턴으로 불린다.

하지만 스프링프레임워크는 이런 싱글톤의 단점을 모두 상쇄하면서 장점만 끌어올려주었다.

 

그것을 싱글톤컨테이너라 한다.

댓글