ObjectFactory, ObjectProvider
- 의존관계를 외부에서 주입(DI) 받는 게 아니라 이렇게 직접 필요한 의존관계를 찾는 것을 Dependency Lookup (DL) 의존관계 조회(탐색) 이라 한다.
- 지정한 빈을 컨테이너에서 대신 찾아주는 DL 서비스를 제공하는 것이 바로 ObjectProvider이다. 참고로 과거에는 ObjectFactory가 있었는데, 여기에 편의 기능을 추가해서 ObjectProivder가 만들어졌다.
package hello.core.scope;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Scope;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import static org.assertj.core.api.Assertions.assertThat;
public class SingletonWithPrototypeTest1 {
@Test
void singletonClientUsePrototype() {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(ClientBean.class, PrototypeBean.class);
ClientBean clientBean1 = ac.getBean(ClientBean.class);
int count1 = clientBean1.logic();
assertThat(count1).isEqualTo(1);
ClientBean clientBean2 = ac.getBean(ClientBean.class);
int count2 = clientBean2.logic();
assertThat(count2).isEqualTo(1);
}
static class ClientBean {
@Autowired
private ObjectProvider<PrototypeBean> prototypeBeanProvider;
public int logic() {
PrototypeBean prototypeBean = prototypeBeanProvider.getObject();
prototypeBean.addCount();
int count = prototypeBean.getCount();
return count;
}
}
@Scope("prototype")
static class PrototypeBean {
private int count = 0;
public void addCount() {
count++;
}
public int getCount() {
return count;
}
@PostConstruct
public void init() {
System.out.println("PrototypeBean.init " + this);
}
@PreDestroy
public void destroy() {
System.out.println("PrototypeBean.destroy");
}
}
}
- 실행해보면 prototypeBeanProvider.getObject()을 통해서 항상 새로운 프로토타입 빈이 생성되는 것을 확인할 수 있다.
- ObjectProvider의 getObject()를 호출하면 내부에서는 스프링 컨테이너를 통해 해당 빈을 찾아서 반환한다. (DL)
- 스프링이 제공하는 기능을 사용하지만, 기능이 단순하므로 단위 테스트를 만들거나 mock 코드를 만들기는 훨씬 쉬워진다.
- ObjectProvider는 지금 딱 필요한 DL 정도의 기능만 제공한다.
- 특징 ObjectFactory: 기능이 단순, 별도의 라이브러리 필요 없음, 스프링에 의존
- ObjectProvider: ObjectFactory 상속, 옵션, 스트림 처리 등 편의 기능이 많고, 별도의 라이브러리 필요 없음, 스프링에 의존
결론
싱글톤 빈과 함께 사용할 때는 ObjectProvider 를사용하는 것을 권장하지만, Spring이 아닌 자바에서 사용하게 된다면 javax.inject.Provider를 사용해야 되지만, 거의 사용할 일이 없을 것 같으므로 인지만 하고 넘어갔다. 그리고 무엇보다도 싱글톤과 함께 사용되는 프로토타입 빈이라면 ObjectProivder.getBean을 통해서 가져와야 된다는 것을 인지하고 있자.
이 글은 인프런의
제목 : 스프링 핵심 원리 - 기본편
강사 : 김영한 님의 동영상을 참조해 만들었습니다.
'Spring > 스프링 핵심 원리 - 기본편' 카테고리의 다른 글
빈 스코프 - 웹 스코프 (0) | 2022.03.21 |
---|---|
빈 스코프 - 프로토타입 스코프, 싱글톤 빈과 함께 사용시 문제점 (0) | 2022.03.21 |
빈 생명주기 콜백 (0) | 2022.03.18 |
의존관계 자동 주입 - 자동, 수동의 올바른 실무 운영 기준 (0) | 2022.03.18 |
의존관계 자동 주입 - 애노테이션 직접 만들기 (0) | 2022.03.18 |