빈 스코프 ?
스프링이 지원하는 다양한 스코프
프로토타입 스코프
public class PrototypeTest {
@Test
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");
}
}
}
/* 출력 결과
find prototypeBean1
PrototypeBean.init
find prototypeBean2
PrototypeBean.init
prototypeBean1 = hello.core.scope.PrototypeTest$PrototypeBean@c05fddc
prototypeBean2 = hello.core.scope.PrototypeTest$PrototypeBean@25df00a0
*/
프로토타입 빈 + 싱글톤 문제점
해결 방법
싱글톤 빈이 프로토타입 빈을 사용할 때 마다 스프링 컨테이너에 요청
ObjectFactory, ObjectProvider
@Autowired
private ObjectProvider<PrototypeBean> prototypeBeanProvider;
public int logic() {
PrototypeBean prototypeBean = prototypeBeanProvider.getObject(); // getObject() 를 호출하면 내부에서는 스프링 컨테이너를 통해 해당 빈을 찾아서 반환(DL)
prototypeBean.addCount();
int count = prototypeBean.getCount();
return count;
}
JSR-330 Provider
@Autowired
private Provider<PrototypeBean> prototypeBeanProvider;
public int logic(){
PrototypeBean prototypeBean = prototypeBeanProvider.get(); // 새로운 프로토타입 빈이 생성됨
prototypeBean.addCount();
int count = prototypeBean.getCount();
return count;
}
웹 스코프
종류
스프링 부트는 웹 라이브러리가 없으면 AnnotationConfigApplicationContext
를 기반으로 애플리케이션을 구동
→ 웹 라이브러리가 추가되면 웹과 관련된 추가 설정과 환경들이 필요하므로AnnotationConfigServletWebServerApplicationContext
를 기반으로 애플리케이션을 구동
스코프와 프록시
@Component
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class MyLogger {
}
TARGET_CLASS
를 선택INTERFACES
를 선택MyLogger
의 가짜 프록시 클래스를 만들어두고 HTTP request와 상관 없이 가짜 프록시 클래스를 다른 빈에 미리 주입해 둘 수 있다.myLogger
라는 이름으로 가짜 프록시 객체를 등록 → 의존 관계에도 가짜 프록시 객체 주입myLogger
를 찾는 방법을 알고 있음→ 싱글톤을 사용하는 것 같지만 다르므로 주의, 이런 특별한 스코프는 필요한 곳에서만 최소화하여 사용하지 않으면 유지보수에 어려움