🔭

[토비의 스프링] 1. 오브젝트와 의존관계 - 싱글톤 레지스트리와 오브젝트 스코프

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

스프링의 애플리케이션 컨텍스트와 기존에 만들었던 DaoFactory는 중요한 차이점이 있습니다.

오브젝트의 동일성과 동등성 ?

자바에서는 두 개의 객체가 같은가? 에는 2가지 관점이 있습니다.

  1. 완전히 같은 객체인지 비교

    • 동일성(identity)
    • == 연산자로 비교
  2. 같은 정보를 담고 있는 객체인지 비교

    • 동등성(equality)
    • equals() 메서드로 비교

이를 통해서 하고 싶은 말은 스프링은 빈을 요청할 때 매번 동일한 객체(동일성)를 돌려준다는 것입니다.

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

애플리케이션 컨텍스트는 싱글톤을 저장하고 관리하는 싱글톤 레지스트리이기도 합니다.

스프링은 왜 싱글톤으로 빈을 만들까 ?

스프링이 주로 적용되는 대상이 서버 환경이기 때문입니다.

스프링이 처음 설계될때 대규모 엔터프라이즈 서버 환경은 초당 수십, 수백번씩 브라우저나 다른 시스템으로부터 요청을 받아 처리해야하는 높은 성능이 요구 되는 환경이였습니다.
(데이터 액세스 로직, 서비스 로직, 비즈니스 로직 .. 등을 분리하는 계층형 구조)

그런데, 매번 클라이언트에서 요청이 올 때마다 각 로직의 객체를 매번 새로 생성하게 되면 ?

요청 한 번에 5개 객체 + 초 당 500개의 요청이 들어오면 1시간에 9백만개의 객체가 새로 생성됩니다.

이렇게 부하가 걸리면 서버가 감당하기 힘들기 때문에 서버 환경에서는 싱글톤 사용이 권장됩니다.

스프링은 IoC 컨테이너 + 싱글톤 레지스트리

스프링은 직접 싱글톤 형태의 객체를 만들고 관리하는 기능을 제공합니다.

이게 바로 싱글톤 레지스트리 (singleton registry)

싱글톤 레지스트리의 장점은 평범한 자바 클래스를 싱글톤으로 활용하게 도와준다는 점입니다.

기존 싱글톤 패턴을 적용하려면 private 생성자 + static 메서드로 구현해야함)

싱글톤으로 사용돼야 하는 상황이 아닌 경우 (Ex: 테스팅 환경) 에도 자유롭게 여러 객체를 생성해서 사용 가능합니다.

싱글톤으로 만들어지기 때문에 주의 해야할 점

멀티스레드 환경에서는 싱글톤 객체 하나를 여러 스레드에서 나누어 사용할 수 있습니다.

따라서, 싱글톤은 기본적으로 인스턴스 변수의 값을 변경하는 방식으로 만들지 않습니다.

단, 읽기 전용 값이라면 인스턴스 변수를 사용하는 것에 제약이 없다 !

그래서 메서드 파라미터, 로컬 변수, 리턴 값 등을 이용합니다.

이들은 매번 새로운 값을 저장할 독립적인 공간(스택) 에서 만들어집니다.

따라서, 싱글톤이라고 해도 여러 스레드가 값을 덮어쓸 일은 없습니다.


Ex) Java 변수의 종류

public class test {
  int iv;          // 인스턴스 변수 (힙에 저장) -> test 객체가 heap에 저장
  static int cv;   // 클래스 변수 (메모리 맨위에 먼저 올림 - static)
  void method() {
    int lv;        // 로컬 변수 (스택에 저장)
  }

스프링 빈의 스코프

빈의 스코프(scope)란 ?
스프링이 관리하는 객체, 즉 빈이 생성되고 존재하고 적용되는 범위

스프링 빈의 기본 스코프는 싱글톤입니다.

경우에 따라서 싱글톤 외의 스코프를 가질 수 있습니다.

대표적으로 프로토타입 스코프(prototype), 싱글톤과 달리 빈을 요청할 때마다 새로운 객체를 만들어줍니다.

그 외에도 요청 스코프, 세션 스코프 등이 있습니다.

마무리

이상으로 다음 포스팅은 의존관계 주입(DI)에 대해서 알아보겠습니다 🙇🏻‍♂️