본 게시글은 김영한님의 스프링 핵심 원리 기본편을 정리한 글입니다.
빈 스코프란 그냥 번역한 그대로 빈이 존재할 수 있는 범위라는 것이다.
그치만 우리가 알아야 할 것이 이때까지 우리는 이런 존재도 모르고 싱글톤으로 자동으로 설정되어있어서 우리는 빈이 그냥 컨테이너의 시작과 함께 생성되고 컨테이너가 종료될 때까지 유지된다라고 알고 있었는데 사실은 무조건 이런 것은 아니다. 다른 scope도 있는데 한 번 알아보자.
싱글톤 스코프로 빈을 조회하게 되면 어떻게 될까? 물론 우리는 모르고 있었지만 위에서 설명한대로 범위가 스프링 컨테이너 시작부터 컨테이너가 종료때까지 이고 그리고 빈도 싱글톤이기에 단 하나만 있어서 같은 인스턴스의 스프링 빈만 반환을 한다.
클라이언트 A -> memberServicex01
클라이언트 B -> memberServicex01
클라이언트 C -> memberServicex01
동일한 빈을 반환한다.
public class SingletonTest {
@Test
public void singletonTest(){
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(SingletonBean.class);
SingletonBean bean = ac.getBean(SingletonBean.class);
SingletonBean bean2 = ac.getBean(SingletonBean.class);
System.out.println("bean = " + bean);
System.out.println("bean2 = " + bean2);
Assertions.assertThat(bean).isEqualTo(bean2);
ac.close();
}
@Scope("singleton")
static class SingletonBean{
@PostConstruct
public void init(){
System.out.println("SingletonBean.init");
}
@PreDestroy
public void destroy(){
System.out.println("SingletonBean.destroy");
}
}
}
public class PrototypeTest {
@Test
public void prototypeTest(){
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(PrototypeBean.class);
PrototypeBean bean = ac.getBean(PrototypeBean.class);
PrototypeBean bean2 = ac.getBean(PrototypeBean.class);
System.out.println("bean = " + bean);
System.out.println("bean2 = " + bean2);
Assertions.assertThat(bean).isNotEqualTo(bean2);
ac.close();
}
@Scope("prototype")
static class PrototypeBean{
@PostConstruct
public void init(){
System.out.println("PrototypeBean.init");
}
@PreDestroy
public void destroy(){
System.out.println("PrototypeBean.destroy");
}
}
}
프로토타입 스코프는 싱글톤과 반대로 매번 요청이 들어오면 다음과 같은 과정이 있다.
요청 컨테이너
클라이언트 A -> memberServicex01
클라이언트 B -> memberServicex02
클라이언트 C -> memberServicex03
요청을 하고 스프링 빈을 생성한다. 그리고 의존관계까지 주입 후
클라이언트 A
클라이언트 B
클라이언트 C
위와 같이 이후에는 관리를 컨테이너에서 해주지 않는다.
여기서 위 싱글톤과 프로토타입의 큰 차이는 다음과 같다.
싱글톤과 달리 프로토타입은 빈을 생성하고 의존관계를 주입하여주고 초기화까지만 처리를 해준다는 것이다. 프로토타입 빈을 관리하여주는것은 이제 클라이언트에게 달려있다고 한다. 그래서 실제로 코드를 만들어서 테스트를 해보면 @PreDestroy 부분은 출력이 되지 않는다.
각자의 출력물과 실행결과를 보면 알겠지만 빈이 어떻게 생성이 되어서 어떤 범위까지 진행이 되는지도 살펴보았는데 프로토타입의 가장 주요한 특징을 나눠보면 다음과 같다.
프로토타입의 주요한 특징