본문 바로가기

SpringBoot

Singleton pattern

# 싱글톤 ? 

1. 웹어플리케이션에서 싱글톤이 자주 사용되는 이유

스프링은 본래 기업용 온라인 서비스 기술을 지원하기 위해 탄생한 프레임워크.

웹어플리케이션은 특성상 클라이언트의 요청이 많이 존재함. 그러나, 이경우 각 요청마다 객체를 생성하게 되면 메모리부족문제가 발생할 수 밖에 없음.

 

이에따라 싱글톤패턴은 객체를 하나만 생성하여 해당객체를 공유하도록 설계하는 디자인패턴을 제시.

 

 

싱글톤패턴

- 클래스의 인스턴스가 단 한개만 생성되도록 보장하는 디자인패턴.

- 객체인스턴스가 2개 이상 생성하지 못하도록 막아야됨.

 

getInstance()메서드를 통해서만 객체가 조회가능.

new 키워드로 통해 외부에서 객체 인스턴스가 생성되는 것을 막는다.

즉, 생성자를 반드시 private으로 지정해주어야함!

new 키워드 없이 하나의 객체만으로 로직을 수행한다. 다만 클라이언트코드에서 구체클래스에 의존할 수 밖에 없다는 문제점이 있다.

스프링 프레임워크는 객체를 bean으로 등록하면 싱글톤패턴을 자동으로 적용한다.

 

싱글톤 패턴의 문제점

- 코드가 길어짐.

- 클라이언트가 구체클래스에 의존할 수 밖에 없다.

- 테스트하기 어렵다

- 내부 속성을 변경하거나 초기화하기 매우 어렵다.

- private 생성자로인해 상속이 어렵다.

- 유연성이 떨어진다.

 

=> 스프링프레임워크는 싱글톤 패턴의 문제점을 모두 해결하고, 객체를 싱글톤패턴으로 관리한다!

 

# 싱글톤 컨테이너

- 스프링컨테이너는 싱글톤으로 빈을 관리한다.

- 스프링컨테이너 내부의 빈 저장소는 객체를 미리 생성하여, 관리한다.

- DIP, OCP, 테스트, private생성자로부터 자유롭게 싱글톤패턴을 사용할 수 있다.

- 싱글톤패턴을위한 코드를 별도 삽입할 필요가 없다.

 

스프링프레임워크는 싱글턴 패턴을 적용하나, 클라이언트는 구현체에 의존적이지 않다.
스프링 컨테이너를 통해 싱글톤패턴으로 동작하게 된다. 메모리 효율성 ↑

- 스프링컨테이너는 요청이 올때마다 객체를 생성하는 것이 아니라, 이미 만들어진 객체를 공유하므로 효율적인 재사용이 가능하다.

 

※싱글톤 방식의 주의점!!

- 상태를 유지하지 말 것. (Not Stateful)

- 특정 클라이언트에 의존적인 필드가 있으면 안된다.

- 가급적 읽기만 가능하도록 구현한다.

- 필드가아닌 지역변수, 파라미터, ThreadLocal등을 사용해야한다.

 

 

StateFul한 클래스의 예시
기대값은 10000이어야하나, 객체를 공유하는 싱글톤 패턴의 특징때문에 정합성의 문제가 발생한다.(Stateful하면 안되는 이유이다.)

스프링 빈은 항상 무상태로 설계하자... 공유필드는 되도록 사용하지말자...

 

# Solution

공유필드를 없애고, 지역변수를 리턴하도록 설계.
기존의 공유필드 사용으로 인해 발생하던 문제를 해결하였음.(Local variable)