스프링 빈은 여러가지 Scope를 갖고 있어서 각각의 Scope 마다 라이프 사이클을 달리 한다고 한다.
기본값으로는 모두가 일반적으로 알 고 있는 singleton 방식으로 관리되는 Scope로 사용된다.
하지만, singleton 이외에도 여러 가지 Scope가 더 있다고 한다.
스프링빈을 스프링 컨테이너에 등록할때, 기본값으로 사용되는 Scope이다.
prototype scope는 singleton scope와 달리 스프링 빈이 생성 된 이후 부터는 스프링 컨테이너에서 관리하지 않는다.
즉, 클라이언트 A에서 prototype Scope 범위의 스프링 빈을 요청했다면 항상 새로운 스프링 빈을 생성해서 반환해준다. 따라서, @PostDestroy로 명시된 함수가 호출되지 않는다고 한다. 왜냐하면 스프링 컨테이너에서 더 이상 관리하지 않기 때문이다.
강의에서는 특히, singleton scope와 prototype scope를 함께 사용할때의 주의사항에 대해서 강조해주셨다.
왜냐하면 singleton scope로 관리되고 있는 스프링 빈 내부에서 prototype scope인 스프링 빈을 사용하는 경우, 사용자의 의도와는 달리 prototype scope가 최초로 주입된 이후에는 계속 같은 값을 사용하기 때문이다.
(사실 개발할떄는 당연하게 여겨 질것같긴한데, 망각하기도 쉬울것같다. 왜냐하면 prototype scope 스프링 빈을 사용한다는건 항상 새로운 스프링 빈을 반환받는 용도로 선언했을텐데, singleton scope 내부에서 사용되는 prototype scope는 항상 새로운 스프링빈을 사용하지 않을것이기 때문이다.)
이러한 문제를 해결하기 위해서 여러 가지 대안들이 있지만, ObjectProvider 또는 ObjectFactory 를 사용해서 DI(Dependency Injection)이 아닌 DL(Dependency LookUp)를 사용해서 해결할 수 있다고 한다.
DL 이란 말그대로 주입이 아닌 조회다. 스프링 컨테이너에서 스프링빈을 가져와 주입하는게 아니라 필요할떄마다 스프링 컨테이너에서 빈 객체를 찾아온다.
이렇게 되면 여러 가지 장점들이 있지만, 가장 큰 장점은 스프링빈을 로딩하는 시점을 지연시킬 수 있다는점이다.(항상 DL 또는 DI를 하는게 아니라, 진짜로 사용될떄 스프링빈을 로딩한다.)
물론 ObjectProvider는 스프링에서 알아서 스프링 빈으로 등록해서 관리하고 있는 객체라고 한다.
web Scope중에서 1가지인 request scope는 prototype Scope와 매우 유사하다. 그러나,
request scope인 스프링 빈은 http 요청 당 1개의 스프링빈을 갖게 된다.
prototype과는 유사하게 항상 새롭게 만들어지긴 하지만, 클리언트A 요청이 있을 경우, 그 요청이 존재할떄 까진 항상 동일한 Bean을 사용하게 된다.
그래서 서로 다른 여러 클라이언트들의 http 요청이 존재하는 경우, 각 요청들에 대해서 독립적인 스프링빈을 사용하고 처리할 수 있게 된다.
1) 스프링빈은 기적으로 Singleton Scope로 등록되어 사용된다.
2) 항상 새로운 스프링빈을 사용해야한다면 prototype scope를 정의해서 사용하자.
다만, singleton scope와 함께 사용해야 한다면 ObjectProvider를 사용해서 처리하자.
해당 포스팅은 아래의 강의를 공부 후 개인적으로 정리한 내용입니다.
김영한님의 스프링 기본편