빈 스코프 : 빈이 존재할 수 있는 범위
스프링의 다양한 스코프
싱글톤 : 기본 스코프 시작부터 종료까지 가장 넓은 범위의 스코프
프로토타입: 빈의 생성과 의존관계 주입까지만 관리 매우 짧은 범위의 스코프
웹 관련 스코프
request: 웹 요청이 들어오고 나갈때 까지 유지되는 스코프
session: 웹 세션이 생성되고 종료될 때 까지 유지되는 스코프
application: 웹의 서블릿 컨텍스트와 같은 범위로 유지되는 스코프
@Scope(”prototype” | “singleton” | …) 으로 지정할 수 있다.
프로토타입 빈 요청 시 / 항상 새로운 빈 반환
새로운 빈 생성
DI 및 초기화
응답 후 관리 X
스프링 컨테이너는 빈 생성, DI, 초기화까지만 처리
따라서 @PreDestroy와 같은 종료 메서드가 호출되지 않음
싱글톤 빈에서 프로토타입 빈을 요청하는 상황 가정
프로토타입 빈을 생성하여 싱글톤 빈에게 넘겨줌
싱글톤 빈은 해당 프로토타입 빈을 내부에 저장함
클라리언트가 해당 프로토타입 빈 요청 시 싱글톤 빈 내부에 있는 프로토타입 빈을 반환함
이때, 클라이언트가 받은 프로토타입 빈은 새로이 생성되는 빈이 아님
결과적으로 새롭게 생성되어 받기를 원하는 프로토타입 빈이 아니라 저장되어 있는 필드값을 받는 것이 됨
참고. 여러 싱글톤 빈에서 같은 프로토타입 빈을 주입 받는 경우 각 싱글톤 빈은 다른 프로토타입 빈을 주입 받는다 // 그렇다고 새롭게 생성되는 것과는 다르다.
프로토타입 빈을 주입받는 것이 아니라, 스프링 컨테이너를 주입받아 필요 시점에 스프링 컨테이너에게 요청한다. ⇒ 외부에서 의존관계를 주입받는 것이 아니라 직접 필요한 의존관계를 찾는다 (DL / Dependency Lookup)
cons: 단위 테스트가 어렵고, 스프링 컨테이너에 종속적인 코드가 된다.
DL 정도의 기능만 있으면 되는데 오버 스펙임
ObjectFactory, ObjectProvider 를 사용하여 필요 시에 getObject로 DL을 실행한다
ObjectFactory는 과거에 DL을 지원했던 인터페이스이고, 이를 상속받아 부가 기능을 더 제공하는 것이 ObjectProvider이다.
cons: 스프링에 의존
pros: 단위 테스트가 쉽다, 딱 DL만 제공한다.
JSR-330 Provider 를 사용하여 필요 시 get으로 DL을 실행한다
pros: 간단하다, 스프링에 의존하지 않는다
cons: 라이브러리를 가져와야한다
@Lookup 사용할 수 있지만 위 방법으로 충분하고 고려해야할 내용이 많다
실무에서는 싱글톤 빈으로 대부분의 문제를 해결할 수 있기에 프로토타입 빈은 잘 사용되지 않는다.
ObjectProvider, JSR-330 Provider 같은 경우는 DL을 위해 어디서든 사용될 수 있다.
웹 환경에서만 동작
해당 스코프의 종료 시점까지 관리
request: HTTP 요청 하나가 들어오고 나갈 때 까지 유지되는 스코프
session: HTTP session과 동일한 생명주기
application: 서블릿 컨텍스트와 동일한 생명주기
websocket: 웹 소켓과 동일한 생명주기
웹 스코프도 싱글톤보다 작은 범위의 스코프이므로 프로토타입과 싱글톤을 같이 사용할 때의 문제점이 나타나고 이를 provider로 해결할 수 있다.
@Scope에 proxyMode 변수를 추가로 할당하면 가짜 프록시 객체를 미리 만들어 빈에 미리 주입해줄 수 있다.
클래스면, proxyMode = TARGET_CLASS
인터페이스면, proxyMode = INTERFACE
가짜 프록시 객체는 DL을 실행하는 방법을 가지고 있다.
클라이언트는 가짜와 실제 객체를 구분하지 못한다 (다형성)