✅ 지난 블로깅에서..
거론했던 오브젝트 팩토리와 애플리케이션 컨텍스트와 이어서 연결되는데
직접 오브젝트 팩토리를 통해서 연결한것과 스프링의 @configuration 애노테이션을 통해 애플리케이션 컨텍스트로 사용하는 것과 테스트 결과로 보면 동일하다고 할 수 있는데 하지만 중요한 차이점이 있다.
📌 싱글톤 레지스트리
애플리케이션 컨텍스트를 통해 값을 반환받는다면 동일한 오브젝트를 반환받게 된다
왜 이렇게 작동할까? 그것은 스프링 프레임워크는 엔터프라이즈 시스템을 위해 고안된 기술로 요청이 올 때마다 계속 오브젝트를 생성한다면 서버가 그 부하를 감당하기 어려워지기 때문이다.
서블릿은 자바 엔터프라이즈 분야에서 가장 기본이 되는 서비스 오브젝트로 서블릿은 대부분의 멀티스레드 환경에서 싱글톤으로 동작된다.
서블릿의 클래스당 하나의 오브젝트만 생성하고 클라이언트의 요청을 담당하는 여러 스레드에서 하나의 오브젝트(싱글톤)를 공유해서 사용한다.
하지만 실제로 적용하기에는 무리가 있다.
- private 생성자를 가지고 있어서 상속할 수 없다 그래서 객체지향의 특징을 적용할 수 없다.
- 테스트하기에 난해하거나 또는 할 수 없다.
- 서버환경에서 싱글톤이 하나만 만들어진다고 보장할 수 없다 분산 서버의 경우에는 각 서버에 독립적인 오브젝트가 생성될 것이다.
- 싱글톤의 사용으로 인해 전역상태를 가지는데 그렇게 되면 아무 객체가 자유롭게 수정하고 공유할 수 있게 되는데 이는 객체지향 프로그래밍에서 권장되지 않는 방식이다.
스프링에서는 싱글톤을 만들어서 서비스 오브젝트로 사용하는 것을 지지하지만 싱글톤 패턴은 단점이 있다 그래서 스프링에서 직접
싱글톤 형태의 오브젝트를 만들고 관리하는 싱글톤 오브젝트 기능을 제공하는데 그게 싱글톤 레지스트리다.
스프링의 싱글톤 레지스트리를 사용하면 평범한 자바 클래스도 컨테이너를 통해서 싱글톤 방식으로 관리하게 할 수 있어서 위에 거론된 단점을 상쇄시키게 된다. 제일 중요한 건 스프링의 핵심요소인 객체지향적 설계 방식과 원칙 디자인 패턴을 적용하는데 문제가 없다는 점이다.
무상태 방식(Stateless)
기본적으로 싱글톤은 상태정보를 내부에 가지고 있지 않은 무상태 방식으로 만들어져야 한다.
인스턴스 필드의 값을 변경하고 유지하게 된다면 서버에 적용될 경우 데이터가 엉망이 되는 등의 심각한 문제가 발생할 수 있는데
다만 읽기 전용의 값은 초기화 시점에서 인스턴스 변수에 저장하고 값을 공유받는 것은 문제가 되지 않을 것이다.
그래서 무상태 방식의 클래스로 만들 경우에는 메서드 안에 생성되는 로컬변수에 매번 새로운 값을 저장하는 독립적인 공간이 만들어져서 싱글톤이라 해도 여러 스레드가 변수의 값을 덮어쓰지는 않는다.
이를 통해서 스프링이 빈을 관리하여 초기화를 해주고 나면 이후에는 수정되지 않기 때문에 멀티스레드 환경에서 사용해도 문제가 발생되지 않는다.
📌 오브젝트 스코프
스프링이 관리하는 오브젝트를 빈의 스코프라 하는데 스프링 빈의 기본 스코프는 싱글톤이다.
스프링에서 만들어지는 대부분의 빈은 싱글톤 스코프를 갖는다
경우에 따라 다른 스코프도 가질 수 있는데 대표적으로는..
- 프로토타입 스코프: 싱글톤과 다르게 빈 요청마다 새로운 오브젝트를 생성한다.
- 요청 스코프: 웹에서 새로운 HTTP요청이 생길 때마다 생성된다.
- 세션 스코프: 웹의 세션과 유사한 세션 기반의 스코프
[참고] 토비의 스프링 vol.01