BackEnd 학습/Spring Framework

Spring(스프링) -빈 스코프

잉아당 2023. 5. 1. 18:37
728x90

빈 스코프

  • 싱글톤
    • 기본 스코프
    • 스프링 컨테이너의 시작과 종료까지 유지 됨
  • 프로토타입
    • 스프링 컨테이너가 생성과 의존관계 주입까지만 관여
  • 웹 관련 스코프
    • request
      • 웹 요청이 들어오고 나갈때 까지의 스코프
    • session
      • 쉡 세션이 생성되고 종료될 때까지의 스코프
    • application
      • 서블릿 컨텍스와 같은 범위로 유지되는 스코프

프로토타입 스코프

  • 싱글톤 스코프의 빈을 조회하면 스프링 컨테이너는 항상 같은 인스턴스의 스프링 빈을 반환
  • 프로토타입 스코프를 스프링 컨테이너에 조회하면 스프링 컨테이너는 항상 새로운 인스턴스를 생성해서 반환
  • 스프링 컨테이너는 프로토타입 빈을 생성하고, 의존관계 주입, 초기화까지만 처리
  • 프로토타입 스코프는 종료 메서드가 호출되지 않음

프로토타입 스코프 - 싱글톤 빈과 함께 사용시 문제점

  • 싱글톤 빈이 생성될 때 프로토타입 스코프가 생성되어 주입
  • 이미 주입이 되어져 있기 때문에 사용할 때마다 생성하지 않음
  • 내부 값을 공유해서 사용하게 되는 문제점 발생

프로토타입 스코프 - 싱글톤 빈과 함께 사용시 Provider로 문제 해결

  • DL(Dependency Lookup)
    • 직접 필요한 의존관계를 찾는 것
    • 의존관계 탐색
  • ObjectProvider
    • 지정한 빈을 컨테이너에서 대신 찾아주는 DL 서비스를 제공
    • 과거 ObjectFactory에서 현재 ObjectProvider 사용
    • 컨테이너에서 직접 찾는 것이 아닌 찾아주는 대리자 역할
    • ObjectFactory 상속
    • 별도의 라이브러리 필요 없음
    • 스프링에 의존
    • ObjectFactory
      • 기능이 단순
      • 별도의 라이브러리 필요 없음
      • 스프링에 의존
  • JSR-330 Provider
    • 라이브러리를 추가 해주야함
    • 자바 표준 사용하는 방법
    • 내부에서는 스프링 컨테이너를 통해 해당 빈을 찾아서 반환
  • 프로토타입 빈은 매번 사용할 때 마다 의존관계 주입이 완료된 새로운 객체가 필요하면 사용하면 됨
  • 거의 실무에서 사용되지 않음
  • 다른 컨테이너에서도 사용할 수 있어야한다면 JSR-330을 사용해야 함
  • 다른 컨테이너에서 사용할 일이 없다면 스프링이 제공하는 기능을 사용하면 됨

웹스코프

  • 웹 환경에서만 동작
  • 스프링이 해당 스코프의 종료시점까지 관리
  • → 종료 메서드 호출
  • request
    • HTTP 요청 하나가 들어오고 나갈 때 까지 유지되는 스코프
    • 각 HTTP 요청마다 별도의 빈 인스턴스가 생성되고 관리
  • session
    • HTTP Session과 동일한 생명주기를 가짐
  • application
    • 서블릿 컨텍스트와 동일한 생명주기를 가짐
  • websocket
    • 웹 소켓과 동일한 생명주기를 가짐

request 스코프 예제 만들기

  • 로그에 uuid를 추가하여 각 어떤 요청인지 구분하게 만듬
  • @Scope(”request”)로 지정할 경우 HTTP 요청 당 하나씩 생성되고 요청이 끝날 때 소멸 됨
  • request 스코프의 빈을 주입 받을 경우 오류 발생
  • → 해당 스코프는 요청이 발생하고 요청이 끝날 때 까지의 스코프이며 스프링 컨테이너가 실행 될 때 요청이 없어 해당 빈이 생성되지 않으므로 DI에서 오류 발생
  • 로그 기능은 보통 공통 기능이기 때문에 인터셉터나 서블릿 필터나 따로 설정을 통해서 사용 됨

스코프와 Provider

  • 빈 주입을 사용자 요청 시점으로 미루어 에러 해결
  • → ObjectProvider 사용

스코프와 프록시

  • ObjectProvider를 사용하지 않고 proxyMode를 사용
    • 적용대상이 인터페이스면 INTERFACES
    • 적용대상이 클래스면 TARGET_CLASS
    • 가짜 프록시 클래스를 만들어 두고 HTTP request와 상관 없이 가짜 프록시 클래스를 다른 빈에 미리 주입 해 둘 수 있음
    • 가짜 프록시 객체는 내부에 진짜 객체를 찾는 방법을 알고 있음
    • 메서드를 호출하면 프록시 객체의 메서드를 호출하고 해당 메서드에서 실제 빈 객체의 메서드를 호출
    • 가짜 프록시 객체는 원본 클래스를 상속받아서 만들어졌기 때문에 클라이언트 입장에서는 동일하게 사용 가능
    • → 다형성
    • 동작 정리
      • CGLIB 라이브러리로 내클래스를 상속 받은 가짜 프록시 객체를 만들어 주입
      • 가짜 프록시 객체에는 요청이 오면 그 시점에 내부에서 진짜 빈을 요청하는 위임 로직이 존재
      • 가짜 프록시 객체는 실제 request scope와 관계가 없이 가짜이며 내부에 단순 위임 로직만 존재하고 싱글톤 처럼 동작
    • 특징 정리
      • 클라이언트는 프록시 객체 덕분에 편하게 싱글톤 빈 처럼 request scope 사용
      • 핵심은 필요한 시점까지 지연 처리
      • 웹 스코프가 아니여도 프록시 기능 사용 가능
      • 어노테이션 설정만으로 프록시 객체로 대체 가능
      • → 다형성과 DI 컨테이너의 장점
    • 주의점
      • 싱글톤을 사용하는 것 같지만 다르게 동작하기 때문에 주의해서 사용
      • 최소화 해서 사용

 

 

출처 : https://www.inflearn.com/course/스프링-핵심-원리-기본편

 

스프링 핵심 원리 - 기본편 - 인프런 | 강의

스프링 입문자가 예제를 만들어가면서 스프링의 핵심 원리를 이해하고, 스프링 기본기를 확실히 다질 수 있습니다., - 강의 소개 | 인프런

www.inflearn.com