의존 관계 주입과 초기화는 서로 다른 과정
이후 @PostConstruct 부분이 진행된다.
이때 스프링은 하기 scope에 다음과 같이 지원
SingtonBean에서 PrototypeBean을 의존 관계 주입 받아 함께 사용할 때 PrototypeBean 재생성되지 않고 기존에 생성된 객체가 재사용되는 문제가 발생
singtonBean과 prototypeBean을 함께 사용할 때도 prototypeBean을 계속 초기화하며 사용하기 위해서는 Dependency Lookup(DL) 개념이 필요
전체 코드
public class PrototypeProviderTest {
@Test
void providerTest() {
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 ApplicationContext ac;
public int logic() {
PrototypeBean prototypeBean = ac.getBean(PrototypeBean.class);
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");
}
} }
핵심 코드
@Autowired
private ApplicationContext ac;
public int logic() {
PrototypeBean prototypeBean = ac.getBean(PrototypeBean.class);
prototypeBean.addCount();
int count = prototypeBean.getCount();
return count;
어떻게 ac 가 prototypebean.class를 등록하지도 않고 찾을 수 있을까?
ac는 @Autowired를 통해 앞에서 만들어놓은 ClientBean.class, PrototypeBean.class를 등록한 DI 컨테이너를 주입 받음
void providerTest() {
AnnotationConfigApplicationContext ac = new
AnnotationConfigApplicationContext(ClientBean.class, PrototypeBean.class);
이때 등론된 PrototypeBean.class의 scope는 "prototype"
prototype은 bean 객체를 조회 할 때 생성된 bean 객체를 가져오는 것이 아닌 조회 후 가져온다.
문제점
스프링 컨테이너에 매우 의존적
이로 인해 단위 테스트가 힘들어짐
@Autowired
// 기존
// private ApplicationContext ac;
// 수정
@Autowired
private ObjectProvider<PrototypeBean> prototypeBeanProvider;
public int logic() {
PrototypeBean prototypeBean = ac.getBean(PrototypeBean.class);
prototypeBean.addCount();
int count = prototypeBean.getCount();
return count;
