[Spring] DL과 Provider

Bam·2024년 10월 21일
0

Spring

목록 보기
46/48
post-thumbnail

지난 포스트에서 다룬 빈 스코프의 연장된 이야기입니다.

싱글톤 빈과 프로토타입 빈을 동시에 사용한다면?

만약 싱글톤 빈이 프로토타입 빈을 호출하는 형식으로 설계가 된다면 어떻게 될까요?

싱글톤 빈과 프로토타입 빈의 기능을 생각해봤을 때, 싱글톤 빈이 호출될 때 마다 프로토타입 빈이 생성되기를 기대하겠지만 실제 동작은 그것과 다르게 동작합니다.

왜냐하면 싱글톤 빈은 스프링 컨테이너가 시작되면서 빈이 등록되는데 이때 프로토타입 빈을 요청하고 프로토타입 빈을 주입받게 됩니다.

이 과정에서 싱글톤 빈에는 처음 호출된 프로토타입 빈이 계속 유지됩니다. 왜냐하면 프로토타입 빈은 싱글톤 빈은 한 번만 호출 된 후 컨테이너 종료시까지 재호출 없이 유지되기 때문입니다. 그래서 싱글톤 빈에는 처음 호출 했던 프로토타입 빈이 계속 주입되어 유지되게 됩니다.

그래서 원래 의도처럼 싱글톤 빈을 호출할 때마다 새로운 프로토타입 빈을 생성하려면 어떻게 해야 할까요?


DL, Dependency Lookup 의존관계 조회

위와 같은 상황을 해결하기 위해서는 특정 시점(프로토타입 빈을 새로 만들고자 하는 시점)에 의존성을 요청해서 프로토타입 빈을 주입받아야 합니다. 이를 구현하기 위한 방법이 바로 DL입니다.

DL은 의존관계가 필요한 객체에서 컨테이너에 의존성을 직접 요청(조회)하는 방식입니다. 생성자 등을 통해 외부에서 주입받는DI와는 다르게 DL은 의존성을 요청한 시점에 컨테이너로부터 가져오게 됩니다.

DI는 의존성을 외부에서 주입받는 것이고, DL은 의존성을 직접 찾는 것을 의미합니다.


방법 1. 스프링 ObjectProvider, ObjectFactory

첫 번째 방법은 스프링에서 제공하는 ObjectProvider, ObjectFactory를 사용하는 방법입니다.

ObjectFactorygetObject()라는 메소드 하나만을 제공하는데요. 이 메소드는 객체의 인스턴스를 반환해줍니다.

ObjectProviderObjectFactory를 상속받아서 더 많은 기능들을 제공합니다.getObject()를 포함해서 If가 붙은 옵션부 인스턴스 취득이나 스트림에 관한 내용까지 다양한 기능들을 제공해주고 있음을 볼 수 있습니다.

@Autowired
private ObjectProvider<프로토타입_빈_타입> beanProvider;

public void method() {
	 프로토타입_빈_타입 bean = beanProvider.getObject();	<- 의존관계 조회
}

위와 같이 작성하면 메소드 호출시점마다 빈을 요청해서 찾게 되므로 싱글톤 빈 내부여도 새로운 프로토타입 빈이 생성되어서 동작하게 됩니다.


방법 2. 자바 표준 Provider

ObjectProvider, ObjectFactory는 심플하고 좋은 방법이지만 다음과 같은 단점이 존재합니다.

  • ObjectProvider, ObjectFactory는 스프링이 제공하는 기능이므로 스프링 프레임워크가 없다면 동작하지 않습니다.

스프링 프레임워크를 사용하지 않는다면 자바 표준으로 사용하는 inject라이브러리의 Provider를 사용해야합니다.

스프링부트 3.X.X 기준으로 jakarta.inject:jakarta.inject-api 라이브러리를 Maven이나 Gradle에 추가한 후에 사용해야합니다.

사용법도 간단합니다. 인스턴스를 가져오는 get() 메소드 하나만 있습니다.

@Autowired
private Provider<프로토타입_빈_타입> provider;

public void method() {
	 프로토타입_빈_타입 bean = provider.get();	<- 의존관계 조회
}

마무리

오늘은 싱글톤 빈과 프로토타입 빈을 동시에 사용하는 것으로 예제를 들었지만 DL이 필요하다면 사용할 수 있는 Provider에 대해서 알아봤습니다.

그래서 결국 뭐쓰라는거지?싶으실수도 있을까봐 결론은 스프링만 사용한다면 스프링에서 제공하는 ObjectProvider를 사용하고 스프링 외의 다른 프레임워크 컨테이너를 사용한다면 자바 표준 Provider를 선택하시면 된다라고 할 수 있습니다.

0개의 댓글