본문 바로가기

스터디/토비의 스프링 3.1

[토비의 스프링] 1.6 싱글톤 레지스트리와 오브젝트 스코프

1. 6 싱글톤 레지스트리와 오브젝트 스코프

오브젝트 팩토리인 DaoFactory와 @Configuration 어노테이션이 추가되어 애플리케이션 컨텍스트를 통해 사용하는 것은 차이점이 있다.

  1. DaoFactory의 userDao()를 여러번 호출할 때는 새로운 new 연산자에 의해 다른 오브젝트가 만들어져 돌아온다.

  2. 애플리케이션 컨텍스트로 getBean()을 사용하여 userDao()메소드를 호출하는 경우는 동일한 오브젝트가 생성된다.

차이점은 바로 애플리케이션 컨텍스트가 싱글톤 레지스트리로서 동작하고 있기 때문이다.

스프링은 싱글톤으로 빈을 만든다. 서버 환경에서 주로 사용되어 매번 클라이언트의 요청을 받을 때마다 각 로직을 담당하는 오브젝트를 새로 만들어서 사용하게 될 경우 매우 많은 오브젝트가 새롭게 생성되어 부하가 걸리게 되고 서버가 감당하기 힘들어진다. 그래서 엔터프라이즈 분야에서는 서비스 오브젝트라는 개념을 일찍부터 사용해왔으며 대표적인 예시로 서블릿이 있다. 서블릿은 클래스당 하나의 오브젝트만 만들어두고 사용자의 요청을 담당하는 여러 스레드에서 하나의 오브젝트를 공유해 동시에 사용한다.

싱글톤 패턴의 한계

  • 클래스 밖에서는 생성하지 못하도록 생성자를 private으로 만든다.

    • 따라서 상속할 수 없으며 이를 이용한 다형성을 적용할 수 없다.

      (static 필드, 메소드를 정의하는 것도 동일한 문제를 발생시킨다.)

  • 생성된 싱글톤 오브젝트를 저장할 수 있는 static 필드를 정의한다.

  • 스태틱 팩토리 메소드인 getInstance()를 만들고 메소드가 최초로 호출되는 시점에서 한번만 오브젝트가 만들어지게 한다.

싱글톤 패턴의 문제점

  • 테스트가 어렵다.

  • 서버 환경에서는 싱글톤이 하나만 만들어지는 것을 보장하지 못한다.

  • 싱글톤의 사용은 전역 상태를 만들 수 있기 때문에 바람직하지 못하다.

싱글톤 레지스트리

스프링은 서버환경에서 싱글톤이 만들어져서 서비스 오브젝트 방식으로 사용되는 것을 적극 지지한다.

==싱글톤 레지스트리== 를 통해 스프링이 직접 싱글톤 형태의 오브젝트를 만들고 과리하는 기능을 제공한다.

싱글톤 레지스트리의 장점

  • 스태틱 메소드와 private 생성자가 아니더라도 싱글톤으로 활용하게 해준다. 따라서 싱글톤 방식으로 사용될 애플리케이션 클래스라도 public 생성자를 가질 수 있다. 또한 테스트 환경에서 자유롭게 테스트할 수 있다.

  • 싱글톤 패턴과는 다르게 스프링이 지지하는 객체지향적인 설계방식과 원친, 디자인 패턴(싱글톤 패턴은 제외)등을 적용하는 데 아무련 제약이 없다는 점이다.

싱글톤과 오브젝트의 상태

멀티스레드 환경에서 동시에 접근하여 사용되는 상황이라면 싱글톤은 stateless 방식으로 만들어져야 한다

stateless한 방식으로 만들어진 싱글톤을 다루기 위해서는 로컬 변수, 리턴 값등을 이용하면 된다. 또는 읽기전용의 정보라면 싱글톤에서 인스턴스 변수로 사용해도 좋지만 단순한 읽기전용 값이라면 static final 또는 final로 선언하는 편이 좋다.

스프링 빈의 스코프

스프링이 관리하는 오브젝트, 즉 빈이 생성되고 존재하고 적용되는 범위를 빈의 스코프라고 한다.

스프링 빈의 기본 스코프는 싱글톤이다. 컨테이너 내에 한 개의 오브젝트만 만들어져서 강제로 제거하지 않는 한 스프링 컨테이너가 존재하는 동안 계속 유지된다.

경우에 따라서 프로토타입 스코프, 요청스코프, 세션스코프가 있다.