-
프로토타입 스코프 - 싱글톤 빈과 함께 사용시 Provider로 문제 해결spring/스프링 핵심 원리 강의 내용 정리 2023. 12. 12. 18:00
싱글톤 빈과 프로토타입 빈을 함께 사용할 때, 어떻게 하면 사용할 때 마다 항상 새로운 프로토타입 빈을 생성할 수 있을까?
스프링 컨테이너에 요청
- 가장 간단한 방법은 싱글톤 빈이 프로토타입을 사용할 때 마다 스프링 컨테이너에 새로 요청하는 것이다- 실행해보면 ac.getBean() 을 통해서 항상 새로운 프로토타입의 빈이 생성되는 것을 확인할 수 있다
- 의존관계를 외부에서 주입(DI) 받는게 아니라 이렇게 직접 필요한 의존관계를 찾는 것을
Dependency Lookup (DL) 의존관계 조화(탐색) 이라고 한다
- 그런데 이렇게 스프링 애플리케이션 컨텍스트 전체를 주입받게 되면, 스프링 컨테이너에 종속적인 코드가 되고,
단위 테스트도 어려워진다
- 지금 필요한 기능은 프로토타입 빈을 컨테이너에서 대신 찾아주는 DL 정도의 기능만 제공하는 무언가가 있으면 된다
스프링에는 이미 모든게 준비되어 있다
ObjectFactory, ObjectProvider
- 지정한 빈을 컨테이너에서 대신 찾아주는 DL 서비스를 제공하는 것이 바로 @ObjectProvider 이다
참고로 과거에는 ObjectFactory 가 있었는데, 여기에 편의 기능을 추가해서 @ObjectProvider 가 만들어졌다count = 1, 1 로 같은 값이며 인스턴스 또한 두개가 생성 되었다
- 실행해보면 prototypeBeanProvider.getObject() 을 통해서 항상 새로운 프로토타입 빈이 생성되는 것을 확인할 수 있다
- ObjectProvider 의 getObject() 를 호출하면 내부에서는 스프링 컨테이너를 통해 해당 빈을 찾아서 반환한다 (DL)
- 스프링이 제공하는 기능을 사용하지만, 기능이 단순하므로 단위테스트를 만들거나 mock코드를 만들기는 훨신 쉬워진다
- ObjectProvider는 지금 딱 필요한 DL 정도의 기능만 제공한다
특징
- ObjectFactory : 기능이 단순, 별도의 라이브러리 필요 없음, 스프링에 의존
- ObjectProvider : ObjectFactory 상속, 옵션, 스트림 처리등 편의 기능이 많고, 별도의 라이브러리 필요 없음, 스프링 의존
JSR-330 Provider
마지막 방법은 javax.inject.Provider 라는 JSR-330 자바 표준을 사용하는 방법이다
스프링 부트 3.0은 jakarta.inject.Provider 사용한다
이 방법을 사용하려면 다음 라이브러리를 gradle에 추가해야 한다- 실행해보면 provider.get() 을 통해서 항상 새로운 프로토타입 빈이 생성되는 것을 확인할 수 있다
- provider 의 get() 을 호출하면 내부에서는 스프링 컨테이너를 통해 해당 빈을 찾아서 반환한다 (DL)
- 자바 표준이고, 기능이 단순하므로 단위테스트를 만들거나, mock 코드를 만들기는 훨신 쉬워진다
- Provider 는 지금 딱 필요한 DL 정도의 기능만 제공한다
특징
- get() 메서드 하나로 기능이 매우 단순하다
- 별도의 라이브러리가 필요하다
- 자바 표준이므로 스프링이 아닌 다른 컨테이너에서도 사용할 수 있다
정리
- 그러면 프로토타입 빈을 언제 사용할까?
매번 사용할때 마다 의존관계 주입이 완료된 새로운 객체가 필요하면 사용하면 된다
그런데 실무에서 웹 애플리케이션을 개발하다보면, 싱글톤 빈으로 대부분의 문제를 해결할 수 있기 때문에,
프로토타입 빈을 직접적으로 사용하는 일은 매우 드물다
- ObjectProvider, JSR303 Provider 등은 프로토타입 뿐만 아니라 DL이 필요한 경우는 언제든지 사용할 수 있다
참고 : 스프링이 제공하는 메서드에 @Lookup 에노테이션을 사용하는 방법도 있지만,
이전 방법들로 충분하고, 고려해야할 내용도 많아서 생략하겠다
참고 : 실무에서 자바 표준인 JSR-330 Provider를 사용할 것인지, 아니면 스프링이 제공하는 ObjectProvider
를 사용할 것인지 고민이 될 것이다.
ObjectProvider는 DL을 위한 편의 기능을 많이 제공해주고 스프링 외에 별도의 의존관계 추가가 필요 없기
때문에 편리하다. 만약 (정말 그럴일은 없겠지만) 코드를 스프링이 아닌 다른 컨테이너에서도 사용할 수 있어야
한다면 JSR-330 Provider 를 사용해야 한다
스프링을 사용하다 보면 이 기능 뿐만 아니라 자바 표준과 스프링이 제공하는 기능이 겹칠때가 많이 있다
대부분 스프링이 더 다양하고 편리한 기능을 제공해주기 때문에, 특별히 다른 컨테이너를 사용할 일이 없다면
스프링이 제공하는 기능을 사용하면 된다'spring > 스프링 핵심 원리 강의 내용 정리' 카테고리의 다른 글
request 스코프 예제 만들기 (0) 2023.12.12 웹 스코프 (0) 2023.12.12 프로토타입 스코프 - 싱글톤 빈과 함께 사용시 문제점 (0) 2023.12.12 프로토타입 스코프 (0) 2023.12.12 빈 스코프란 (0) 2023.12.12