기본적으로 프로토타입 빈을 쓴다는 것은 사용할 때 마다 새롭게 생성해서 사용하려는 의도임.
public class SingletonWIthPrototypeTest1 {
@Test
void prototypeFind(){
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(PrototypeBean.class);
PrototypeBean prototypeBean1 = new PrototypeBean();
prototypeBean1.addCount();
assertThat(prototypeBean1.getCount()).isEqualTo(1);
PrototypeBean prototypeBean2 = new PrototypeBean();
prototypeBean2.addCount();
assertThat(prototypeBean2.getCount()).isEqualTo(1);
}
@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(2);
}
@Scope("singleton")
static class ClientBean{
private final PrototypeBean prototypeBean;
@Autowired
public ClientBean(PrototypeBean prototypeBean){
this.prototypeBean = prototypeBean;
}
public int logic(){
prototypeBean.addCount();
return prototypeBean.getCount();
}
}
@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");
}
@PreDestroy
public void destroy(){
System.out.println("PrototypeBean.destroy");
}
}
}
위 같은 경우 싱글톤 빈이 프로토타입 빈을 가지고 사용하는 경우인데, 뭐 당연하게도 이미 싱글톤 빈에 의존관계 주입을 해줬기 때문에 계속해서 프로토타입 빈이 싱글톤 빈 안에 남아있음.
프로토타입 빈을 사용하려는 의도인 호출할 때마다 새로 생성과는 거리가 멈.
뭐 굳이 제대로 프로토타입은 호출할 때마다 새로 생성하게끔 하려면
@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);
}
@Scope("singleton")
static class ClientBean{
// private final PrototypeBean prototypeBean;
@Autowired
ApplicationContext ac;
// @Autowired
// public ClientBean(PrototypeBean prototypeBean){
// this.prototypeBean = prototypeBean;
// }
public int logic(){
PrototypeBean prototypeBean = ac.getBean(PrototypeBean.class);
prototypeBean.addCount();
return prototypeBean.getCount();
}
}
이렇게 하면 되긴 하는데..
이렇게 스프링 컨텍스트 전체 주입받는 건 컨테이너에 종속적인 코드가 되고 단위 테스트도 어려워 짐.
물론 참고로, 주입받는 시점에서 여러 빈에서 같은 프로토타입 빈을 주입받으면, 그 때는 계속 새로 생성한다.
'스프링 > 1. 스프링 핵심 원리' 카테고리의 다른 글
49강. 웹 스코프 (0) | 2023.07.24 |
---|---|
48강. Provider (0) | 2023.07.24 |
46강. 프로토타입 빈. (0) | 2023.07.24 |
45강. 빈 스코프 (0) | 2023.07.23 |
44강. @PostConstruct, @PreDestroy 로 콜백 (0) | 2023.07.23 |