[Spring] 싱글톤 레지스트리와 스프링의 IoC 컨테이너
0. Intro
[토비의 스프링] 1장 오브젝트와 의존관계 '1.6 싱글톤 레지스트리와 오브젝트 스코프'를 읽고 정리한 내용입니다.
- GitHub PR 링크 : https://github.com/Kimhan-nah/toby-spring/pull/8
[1장 오브젝트와 의존관계] 1.6 싱글톤 레지스트리와 오브젝트 스코프 by Kimhan-nah · Pull Request #8 ·
Issue 1장 오브젝트와 의존관계 #2 정리 싱글톤이 멀티스레드 환경에서 서비스 형태의 오브젝트로 사용되는 경우에는 상태 정보가 없는 무상태(stateless) 방식으로 만들어져야 하는데, ConnectionMaker
github.com
싱글톤이 멀티스레드 환경에서 서비스 형태의 오브젝트로 사용되는 경우에는 상태 정보가 없는 무상태(stateless) 방식으로 만들어져야 하는데, ConnectionMaker처럼 읽기 전용 정보이거나, 자신이 사용하는 다른 싱글톤 빈을 저장하려는 용도라면 인스턴스 변수를 사용해도 괜찮다. 스프링이 한 번 초기화해주고 나면 이후에는 수정되지 않기 때문에 멀티스레드 환경에서 사용해도 아무런 문제가 없다.
1. 싱글톤 레지스트리란?
IoC 컨테이너는 싱글톤 레지스트리의 역할을 한다.
싱글톤 레지스트리란 싱글톤을 저장하고 관리하는 것을 말한다. 여기서 싱글톤은 '하나의 인스턴스만 존재하는 객체'이다.
즉 다시 말해 싱글톤 레지스트리는 '하나의 인스턴스만 존재하는 객체'들을 저장하고 관리하는 것이다.
2. 스프링에서 싱글톤으로 빈을 만드는 이유
스프링이 주로 적용되는 대상이 자바 엔터프라이즈 기술을 사용하는 서버 환경인데, 이러한 서버 애플리케이션에서 싱글톤 사용이 권장된다.
서블릿 같은 서비스 오브젝트는 대부분 멀티스레드 환경에서 싱글톤으로 동작한다. 사용자의 요청을 담당하는 여러 스레드에서 하나의 오브젝트를 공유해 동시에 사용하는 것이다.
그 이유는 매번 클라이언트에서 요청이 올 때마다 각 로직을 담당하는 오브젝트를 새로 만들면 서버가 감당하기 힘들기 때문이다.
서버 환경에서는 서비스 싱글톤의 사용이 권장되며 따라서 스프링에서도 싱글톤으로 빈을 생성하고 관리한다.
3. 하지만, 싱글톤 패턴에도 주의할 점이 있다!
싱글톤은 멀티 스레드 환경이라면 여러 스레드가 동시에 접근해서 사용할 수 있으므로 상태 관리에 주의해야 한다.
싱글톤은 상태 정보를 내부에 갖고 있지 않은 무상태(stateless) 방식으로 만들어져야 한다.
각 요청에 대한 정보, DB나 서버의 리소스로부터 생성한 정보는 파라미터와 로컬 변수, 리턴 값 등을 이용한다. 메소드 파라미터나, 로컬 변수는 매번 새로운 값을 저장할 독립적인 공간이 만들어지기 때문에 싱글톤이라고 해도 여러 스레드가 변수 값을 덮어쓸 일이 없다.
단, 읽기 전용의 속성을 가진 정보이거나, 자신이 사용하는 다른 싱글톤 빈을 저장하려는 용도라면 인스턴스 변수를 사용해도 좋다.
4. 싱글톤의 단점을 개선해주는 스프링 싱글톤 레지스트리 IoC 컨테이너
자바에서 싱글톤은 여러 어려움과 한계가 있다. 단점은 아래 4가지가 있다.
- private 생성자로 상속이 불가능하다는 것
- 테스트가 힘들다는 것
- 서버 환경에서는 싱글톤이 하나만 만들어지는 것을 보장하지 못한다는 것
- 전역 상태를 만들 수 있기 때문에 바람직하지 못하다는 것
이러한 단점들 때문에 스프링은 직접 싱글톤 형태의 오브젝트를 만들고 관리하는 기능(싱글톤 레지스트리)을 제공하며, public 생성자도 가질 수 있게 된다.
5. 스프링 빈의 스코프
빈이 생성되고, 존재하고, 적용되는 범위를 빈의 스코프(scope)라고 한다.
스프링 빈의 기본 스코프는 '싱글톤'이다. 싱글톤 스코프는 컨테이너 내에 한 개의 오브젝트만 만들어져서, 강제로 제거하지 않는 한 계속 유지된다. 스프링에서 만들어지는 대부분의 빈은 싱글톤 스코프를 갖는다.
그 외에 프로토타입(prototype) 스코프, 요청(request) 스코프, 세션(session) 스코프 등이 있다.