Development/Spring

빈 스코프

우봉수 2023. 3. 21. 15:35

빈 스코프

  • 스프링 빈은 기본적으로 싱글통 스코프(빈이 존재할 수 있는 범위)로 생성된다.
  • 빈 스코프 종류
    • 싱글톤: 기본 스코프, 스프링 컨테이너의 시작과 종료까지 유지되는 가장 넓은 범위의 스코프
    • 프로토타입: 스프링 컨테이너는 프로토타입 빈의 생성과 의존관계 주입까지만 관야하고 더는 관리하지 않는 매우 짧은 범위의 스코프이다.
    • 웹 관련 스코프
      • request: 웹 요청이 들어오고 나갈때 까지 유지되는 스코프이다.
      • session: 웹 세션이 생성되고 종료될 때 까지 유지되는 스코프이다.
      • application: 웹의 서블릿 컨텍스와 같은 범위로 유지되는 스코프이다.

프로토타입 스코프

  • 싱글톤 스코프의 빈과 다르게 프로토타입 스코프는 스프링 컨테이너에서 조회하면 항상 새로운 인스턴스를 생성해서 반환한다. 그후 스프링 컨테이너는 해당 빈을 관리하지 않는다.
  • 프로트타입 빈을 관리할 책임은 프로토타입 빈을 받은 클라이언트에 있다 그래서 @PreDestory 같은 종료 메서드가 호출되지 않는다.
    • 만약 destory 메소드 호출이 필요하다면 직접 호출하여 사용해야 한다.
  • 싱글톤 빈과 같이 사용시 문제점
    • 상황: sigleton으로 등록된 Bean이 prototype으로 등록된 빈을 의존하고 있는 경우
    • 복수의 클라이언트가 해당 기능을 사용할 시 SingletonBean이 내부에 가지고 있는 PrototypeBean은 이미 과거에 주입이 끝난 빈이기 때문에 기존의 값을 그대로 가지고 있어 잘못된 값을 가져오게 된다.
  • 해결법: 의존관계 조회(탐색) DL
    • 싱글톤 빈이 프로토타입 빈을 사용할 때 마다 스프링 컨테이너에 새로 요청하는 방법. (==빈의 생성을 지연하는 방법)
      • ObjectProvider<PrototypeBean> 스프링 표준
    @Autowired
    private ObjectProvider<PrototypeBean> prototypeBeanProvider;
    
    public int logic(){
                PrototypeBean prototypeBean = prototypeBeanProvider.getObject();
                prototypeBean.addCount();
                return prototypeBean.getCount();
    }
    
    • JSR-330 Provider
      • jakarta.inject.Provider 자바 표준
    @Autowired
            private Provider<PrototypeBean> prototypeBeanProvider;
            public int logic(){
                PrototypeBean prototypeBean = prototypeBeanProvider.get();
                prototypeBean.addCount();
                return prototypeBean.getCount();
            }
    

웹 스코프

  • 특징:
    • 웹 환경에서만 동작하는 빈이다.
    • 웹 스코프틑 프로토타입과 다르게 스프링이 스코프의 종료시점까지 관리한다.
  • 종류
    • request: HTTP 요청 하나가 들어오고 나갈 때 까지 유지되는 스코프, 각각의 HTTP 요청마다 별도의 빈 인스턴스가 생성되고, 관리된다.
      • HTTPrequest 요청 마다 각각 빈이 할당된다. (단 같은 클라이언트의 요청이면 동일한 빈이 사용됨)
      • @Scope(value = "request",proxyMode = ScopedProxyMode.TARGET_CLASS) 해당 기능을 사용하여 프록시객체(가짜 객체)를 사용하여 마치 싱글톤 빈 처럼 사용이 가능하다.
        • 단지 애노테이션 설정 변경만으로 원본 객체를 프록시 객체로 대체할 수 있다. 이것이 바로 다형성과 DI 컨테이너가 가진 큰 장점이다.
    • session: HTTP Session과 동일한 생명주기
    • application: 서블릿 컨텍스트와 동일한 생명주기를 가지는 스코프
    • websocket: 웹 소켓과 동일한 생명주기를 가지는 스코프