개인 공부 (23.07~

싱글톤 패턴 구현

Song쏭 2023. 12. 12. 23:24

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

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

 

그럼 같은 요청이 올 때 마다 고객은 다르니까 여러개 객체를 생성해서 각각의 클라이언트한테 전달해줘야한다.

 

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

고객 트래픽이 초당 100이 나오면 초당 100개 객체가 생성되고 소멸된다. 따라서 메모리 낭비가 심하다.

 

이러한 문제의 해결 방안은 객체가 딱 1개만 생성되고, 공유되도록 설계하면 된다. 이러한 설계는 싱글톤 패턴을 사용하는 것이다.

 

 

 

싱글톤 패턴 적용 방법

어떤 누가 해당 클래스의 객체를 생성하든지

딱 하나만 생성되길 원하는 클래스가 있다.

 

그 클래스로 static 영역에 객체를 딱 1개만 생성해둔다.

 

그리고 이 객체를 누군가가 사용할 때 이 객체만으로 사용하도록 할 것이다.

new를 사용해 새로 객체를 생성하지 못하게 막을 것이다.

 

그렇게 하기 위해

 

먼저

생성자를 private 으로 설정하여 new 키워드를 사용한 객체 생성을 못하게 막는다.

그리고 static 영역에 새로운 메서드를 만들고, 접근제어자는 public으로 해두고

 

반환값은 위에서 만든 static 영역에 있는 객체로 설정한다.

 

그럼 다른 누군가가 외부에서 해당 객체를 사용할 때, new 키워드를 통하여 새롭게 만들지 못하고

만들어둔 메서드를 사용하여 객체를 쓸 수 있다.

 

이렇게하면 결론적으로 하나의 객체를 모두가 계속 사용할 수 있는 것이다. 

이것이 싱글톤 패턴이다.

 

객체를 미리 생성해두는 가장 안전한 이 방법 이외에도 

싱글톤 패턴을 구현하는 방법은 여러가지가 있다.

 

 

위와같은 싱글톤 작업을 우리가 다 할 필요가 없다.

스프링 컨테이너를 쓰면 스프링 컨테이너가 기본적으로 객체를 싱글톤으로 만들어서 관리해준다.

 

 

스프링 컨테이너 덕분에 고객의 요청이 올 때마다 객체를 생성하는 것이 아니라,

이미 만들어진 객체를 공유해서 효율적으로 재사용 할 수 있다.

* 스프링의 기본 빈 등록 방식은 싱글톤이지만, 싱글톤 방식만 지원하는 것은 아니다.

 

 

 

 

싱글톤 방식의 주의점

싱글톤 패턴이든, 스프링 같은 싱글톤 컨테이너를 사용하든, 

객체 인스턴스를 하나만 생성해서 공유하는 싱글톤 방식은 여러 클라이언트가 하나의 같은 객체 인스턴스를 공유하기 때문에

싱글톤 객체는 상태를 유지하게 설계하면 안된다.

 

무상태(stateless)로 설계해야한다.

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

- 특정 클라이언트가 값을 변경할 수 잇는 필드가 있으면 안된다.

- 가급적 읽기만 가능해야 한다.

- 필드 대신에 자바에서 공유되지 않는 지역변수, 파라미터, ThreadLocal 등을 사용해야한다.

 

스프링 빈의 필드에 공유 값을 설정하면 정말 큰 장애가 발생할 수 있다.

 

결론,

공유필드는 조심해야한다.

스프링 빈은 항상 무상태(stateless)로 설계하자!