본문 바로가기
Spring

Singleton Container - 웹 애플리케이션과 Singleton

by Heesu.lee 2020. 12. 2.

Spring 은 태생이 기업용 온라인 서비스 기술을 지원하기 위해 탄생된 기술이었다.

대부분의 Spring Application 은 Web Application 이다. (물론 웹이 아닌 다른 애플리케이션(배치, 데몬) 개발도 얼마든지 개발할 수 있다.)

 

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

싱글톤 없는 웹 애플리케이션

스프링이 아닌 순수한 DI 컨테이너인 AppConfig 는(싱글톤 구현이 아닌 경우) 위와 같이 여러 요청이 생길 때 마다 해당 서비스를 책임지는 객체 인스턴스를 매번 생성하는 문제가 발생한다.

만약 고객의 트래픽이 초당 100이 나온다면 초당 최소 100개의 객체가 생성되고 소멸된다. (의존 관계가 있는 경우 더 많을 수 있다.) 이는 곧 메모리 낭비로 이어지게 된다.

(초당 요청 개수가 그렇게 많지 않다면 문제가 없을 수 있겠지만, 요청이 무수히 많아진다면 이는 문제점이 분명히 될 수 있다.)

 

순수 DI 컨테이너 인스턴스 획득 테스트
요청한 서비스 객체 참조값 비교 결과

위와 같이 요청마다 객체 인스턴스 생성시키는 문제를 해결하기 위한 방법은 단순히 객체를 딱 1개만 생성하고, 요청마다 해당 인스턴스를 공유하도록 설계하면 된다. → "Singleton Pattern" 

 

Singleton Pattern

위에서 언급하였 듯이 싱글톤 패턴이란 클래스의 인스턴스가 딱 1개만 생성되는 것을 보장하는 디자인 패턴이다.

다시말해, 객체 인스턴스를 2개 이상 생성하지 못 하도록 하는 것을 의미한다.

 

구현 방법은 다음 아래와 같다.

  • static 영역에 객체 instanc 를 미리 하나 생성하여 올려둔다. (JVM 클래스 로드 시점)
  • 생성된 인스턴스가 필요하면 오직 getInstance static 메서드를 통해서만 조회할 수 있도록 한다. (해당 메서드는 항상 같은 인스턴스를 반환한다.)
  • 딱 1개의 객체 인스턴스만 존재해야 하므로, 생성자를 private 으로 접근 제어시켜 혹시라도 외부에서 new 키워드로 객체 인스턴스가 생성되는 것을 막는다.

Singleton 구현 예시

위 예시 이외에도 많은 싱글톤 패턴을 구현하는 방법은 많다. 그건 다른 게시글을 통해 만나 볼 수 있도록 하겠다.

 

이제 AppConfig 에 등록된 모든 객체들을 싱글톤 패턴을 적용하면 고객의 요청이 올때 마다 객체를 생성하는 것이 아니라, 이미 만들어진 객체를 공유해서 효율적으로 사용할 수 있다. 하지만, 싱글톤 패턴은 다음과 같은 수 많은 문제점들을 가지고 있다.

 

Singleton Pattern 의 문제점

  • 싱글톤 패턴을 구현하는 코드 자체가 많이 추가된다.
  • 의존 관계상 클라이언트가 구체 클래스에 의존하게 된다. - DIP 위반하게 된다. (ex. getInstance static 메서드)
  • 클라이언트가 구체적인 클래스에 의존하기 때문에, OCP 원칙을 위반할 가능성이 높다. - 참고 객체 지향 설계의 5가지 원칙
  • 테스트하기 어렵다.
  • 내부 속성을 변경하거나 초기화 하기 어렵다.
  • private 생성자로 자식 클래스를 만들기 어렵다.
  • 결론적으로 유연성이 떨어진다. (DI 해주기 굉장히 어려워진다.)
  • 안티 패턴으로 불리기도 한다.

그렇다면, Spring Container (DI 컨테이너, 싱글톤 컨테이너) 는 어떻게 이러한 문제점들을 해결하며 활용하고 있는지 다음 블로그를 통해 알아볼 수 있도록 하겠다.

 

 

참조

  • 해당 게시글은 김영한님의 강좌 스프링 핵심 원리 - 기본편을 바탕으로 작성되었습니다.

 

댓글