PengTory

[Spring] 오브젝트와 의존관계 (4) _ 싱글톤과 오브젝트 본문

Spring

[Spring] 오브젝트와 의존관계 (4) _ 싱글톤과 오브젝트

펭토리 2022. 10. 14. 01:54

싱글톤 레지스트리로서의 애플리케이션 컨텍스트

애플리케이션 컨텍스트는 우리가 만들었던 오브젝트 팩토리와 비슷한 방식으로 동작하는 IoC 컨테이너다. 그러면서 동시에 이 애플리케이션 컨텍스트는 싱글톤을 저장하고 관리하는 싱글톤 레지스트리이기도 하다.

 

서버 애플리케이션과 싱글톤

스프링이 주로 적용되는 대상이 자바 엔터프라이즈 기술을 사용하는 서버환경이기 때문에 스프링은 싱글톤으로 빈을 만드는 것이다.

만약 매번 클라이언트에서 요청이 올 때마다 각 로직을 담당하는 오브젝트를 새로 만들어서 사용한다고 생각해보자. 아무리 자바의 오브젝트 생성과 가비지 컬렉션의 성능이 좋아져도 서버가 감당하기 힘들다. 그래서 엔터프라이즈 분야에서는 서비스 오브젝트라는 개념을 일찍부터 사용해왔다. 서블릿 클래스당 하나의 오브젝트만 만들어두고, 사용자의 요청을 담당하는 여러 스레드에서 하나의 오브젝트를 공유해 동시에 사용한다. 이렇게 애플리케이션 안에 제한된 수, 대개 한 개의 오브제그만 만들어서 사용하는 것이 싱글톤 패턴의 원리다. 따라서 서버환경에서는 서비스 싱글톤의 사용이 권장된다.

 

싱글톤 패턴

싱글톤 패턴은 어떤 클래스를 애플리케이션 내에서 제한된 인스턴스 개수, 이름처럼 주로 하나만 존재하도록 강제하는 패턴이다. 이렇게 하나만 만들어지는 클래스의 오브젝트는 애플리케이션 내에서 전역적으로 접근이 가능하다. 단일 오브젝트만 존재해야 하고, 이를 애플리케이션이 여러 곳에서 공유하는 경우에 주로 사용한다.

 

싱글톤 패턴의 한계

자바에서 싱글톤을 구현하는 방법은 아래와 같다.

  • 클래스 밖에서는 오브젝트를 생성하지 못하도록 생성자를 private으로 만든다.
  • 생성된 싱글톤 오브젝트를 저장할 수 있는 자신과 같은 타입의 스태틱 필드를 정의한다.
  • 스태틱 팩토리 메소드인 getInstance()를 만들고 이 메소드가 최초로 호출되는 시점에서 한 번만 오브젝트가 만들어지게 한다. 생성된 오브젝트는 스태틱 필드에 저장된다. 또는 스태틱 필드의 초기값으로 오브젝트를 미리 만들어둘 수도 있다.
  • 한번 오브젝트(싱글톤)가 만들어지고 난 후에는 getInstance() 메소드를 통해 이미 만들어서 스태틱 필드에 저장해둔 오브젝트를 넘겨준다.

그리고 일반적으로 싱글톤 패턴 구현 방식에는 다음과 같은 문제가 있다.

  • private 생성자를 갖고 있기 때문에 상속할 수 없다.
  • 싱글톤은 테스트하기가 힘들다.
  • 서버 환경에서는 싱글톤이 하나만 만들어지는 것을 보장하지 못한다.
  • 싱글톤의 사용은 전역 상태를 만들 수 있기 때문에 바람직하지 못하다.

 

싱글톤 레지스트리

위에서 공부한 것처럼 자바의 기본적인 싱글톤 패턴의 구현 방식은 여러 가지 단점이 있기 때문에 스프링은 직접 싱글톤 형태의 오브젝트를 만들고 관리하는 기능을 제공하는데 그것이 바로 싱글톤 레지스트리다.

싱글톤 레지스트리의 장점은 스태틱 메소드와 private 생성자를 사용해야 하는 비정상적인 클래스가 아니라 평범한 자바 클래스를 싱글톤으로 활용하게 해준다는 점이다. 가장 중요한 것은 싱글톤 패턴과 달리 스프링이 지지하는 객체지향적인 설계 방식과 원칙, 디자인 패턴 등을 적용하는 데 아무런 제약이 없다는 점이다.

스프링은 IoC 컨테이너일 뿐만 아니라, 고전적인 싱글톤 패턴을 대신해서 싱글톤을 만들고 관리해주는 싱글톤 레지스트리라는 점을 기억해두자. 스프링이 빈을 싱글톤으로 만드는 것은 결국 오브젝트의 생성 방법을 제어하는 IoC 컨테이너로서의 역할이다.

출처: https://withseungryu.tistory.com/74

싱글톤과 오브젝트의 상태

싱글톤은 멀티스레드 환경이라면 여러 스레드가 동시에 접근하여 사용할 수 있다. 따라서 상태 관리에 주의를 기울여야 한다. 기보적으로 싱글톤이 멀티스레드 환경에서 서비스 형태의 오브젝트로 사용되는 경우에는 상태정보를 내부에 갖고 있지 않은 무상태 방식으로 만들어져야 한다. 상태가 없는 방식으로 클래스를 만든 경우에는 파라미터와 로컬 변수, 리턴 값 등을 이용하면 된다. 메소드 파라미터나, 메서드 안에서 생성되는 로컬 변수는 매번 새로운 값을 저장할 독립적인 공간이 만들어지기 때문에 싱글톤이라고 해도 여러 스레드가 변수의 값을 덮어쓸 일이 없다.

 

스프링 빈의 스코프

스프링이 관리하는 오브젝트, 즉 빈이 생성되고, 존재하고, 적용되는 범위를 빈의 스코프 라고 한다. 스프링 빈의 기본 스코프는 싱글톤이다. 경우에 따라서는 싱글톤 외의 스코프를 가질 수 있다.

종류로는 프로토타입 스코프, 요청 스코프, 세션 스코프 등이 있다.

 

 

[참고자료] 토비의 스프링 3.1 Vol.1 스프링의 이해와 원리