2023. 8. 26. 16:46ㆍSpring/[inflearn]스프링 핵심 원리 - 기본편
◎ 프로토타입 스코프
-> 프로토타입 스코프는 스프링 컨테이너에 조회하면 스프링 컨테이너는 항상 새로운 인스턴스를 생성해서 반환한다.
1. 프로토타입 스코프의 빈을 스프링 컨테이너에 요청한다.
2. 스프링 컨테이너는 이 때 프로토타입 빈을 생성하고 의존관계를 주입한다.
3. 스프링 컨테이너는 생성한 프로토타입 빈을 클라이언트에게 반환한다.
4. 모두 반환하면 스프링 컨테이너는 프로토타입 빈을 더 이상 관리하지 않고, 이후 스프링 컨테이너에 같은 요청이 오면 프로토타입 빈을 새로 생성하여 반환한다.
※ 중요 포인트
- 스프링 컨테이너는 프로토타입 빈을 생성하고, 의존관계를 주입하고 초기화까지만 처리한다.
- 클라이언트에 반환한 후에는 더 이상 프로토타입 빈을 관리하지 않는다.
- 프로토타입 빈을 관리할 책임은 프로토타입 빈을 반환받은 클라이언트에게 있다. 그래서 @PreDestroy 같은 종료 메서드가 호출되지 않는다.
◎ 싱글톤 스코프와 프로토타입 스코프 비교
-> 싱글톤 스코프 테스트
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Scope;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
public class SingletonTest {
@Test
void singletonBeanFind(){
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(SingletonBean.class);
SingletonBean singletonBean1 = ac.getBean(SingletonBean.class);
SingletonBean singletonBean2 = ac.getBean(SingletonBean.class);
System.out.println("singletonBean1 = " + singletonBean1);
System.out.println("singletonBean2 = " + singletonBean2);
Assertions.assertThat(singletonBean1).isSameAs(singletonBean2);
ac.close(); // 종료
}
@Scope("singleton") // 싱긍톤 스코프 선언(singleton이 기본값)
static class SingletonBean {
@PostConstruct
public void init(){
System.out.println("SingletonBean.init");
}
@PreDestroy
public void destroy(){
System.out.println("SingletonBean.destroy");
}
}
}
-> 결과
- singletonBean1과 singletonBean2는 모두 같은 인스턴스 빈을 조회하였다.
- 이후 종료 메서드까지 실행되었다.
-> 프로토타입 스코프 테스트
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Scope;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
public class PrototypeTest {
@Test
public void prototypeBeanFind(){
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(PrototypeBean.class);
System.out.println("find prototypeBean1");
PrototypeBean prototypeBean1 = ac.getBean(PrototypeBean.class);
System.out.println("find prototypeBean2");
PrototypeBean prototypeBean2 = ac.getBean(PrototypeBean.class);
System.out.println("prototypeBean1 = " + prototypeBean1);
System.out.println("prototypeBean2 = " + prototypeBean2);
Assertions.assertThat(prototypeBean1).isNotSameAs(prototypeBean2);
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");
}
}
}
-> 결과
- 싱글톤 빈은 스프링 컨테이너 생성 시점에 초기화 메서드가 실행되지만, 프로토타입 스코프 빈은 스프링 컨테이너에서 빈을 조회할 때 생성되고, 초기화 메서드도 생성된다.
- prototypeBean1과 prototypeBean2는 서로 다른 스프링 빈이다. 초기화(PrototypeBean.init())이 2번 실행되었다.
- 싱글톤 빈은 스프링 컨테이너가 관리하여 스프링 컨테이너가 종료될 때 빈의 종료 메서드(destroy())가 실행되지만, 프로토타입 빈은 스프링 컨테이너가 생성, 의존관계 주입, 초기화까지만 관여하기 때문에 초기화 이후는 스프링 컨테이너가 관여하지 않는다. 따라서 스프링 컨테이너가 종료될 떄 @PreDestroy()같은 종료 메서드가 실행되지 않는다.
- 프로토타입 빈에서 종료 메서드를 호출하려면 클라이언트가 직접 호출해야 한다.
-> 프로토타입 스코프에서 종료 메서드 직접 호출
public class PrototypeTest {
@Test
public void prototypeBeanFind(){
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(PrototypeBean.class);
System.out.println("find prototypeBean1");
PrototypeBean prototypeBean1 = ac.getBean(PrototypeBean.class);
System.out.println("find prototypeBean2");
PrototypeBean prototypeBean2 = ac.getBean(PrototypeBean.class);
System.out.println("prototypeBean1 = " + prototypeBean1);
System.out.println("prototypeBean2 = " + prototypeBean2);
Assertions.assertThat(prototypeBean1).isNotSameAs(prototypeBean2);
/*
프로토타입 빈은 초기화 이후는 클라이언트가 직접 관리해야 한다.
따라서 초기화 이후의 종료 메서드를 직접 호출한다.
*/
prototypeBean1.destroy();
prototypeBean2.destroy();
ac.close(); // 종료
}
-> 결과
☆ 참고
'Spring > [inflearn]스프링 핵심 원리 - 기본편' 카테고리의 다른 글
빈 스코프 - 프로토타입 스코프와 싱글톤 빈과 함께 사용 시 Provider로 문제 해결 (0) | 2023.09.18 |
---|---|
빈 스코프 - 프로토타입 스코프와 싱글톤 빈과 함께 사용 시 문제점 (0) | 2023.08.27 |
빈 스코프 (0) | 2023.08.26 |
빈 생명주기 콜백 - 애너테이션(@PostConstruct, @PreDestory) (0) | 2023.08.24 |
빈 생명주기 콜백 - 빈 등록 초기화, 소멸 메서드 (0) | 2023.08.23 |