※ 본문은 김영한 선생님의 인프런 '스프링 핵심 원리 - 기본편' 강의를 듣고 정리한 내용임을 알립니다.
▶ 스프링이 지원하는 스코프
1. 싱글톤 : 기본 스코프, 스프링 컨테이너의 시작과 종료까지 유지되는 가장 넓은 범위의 스코프
2. 프로토타입 : 스프링 컨테이너가 프로토타입의 빈 생성과 의존관계 주입까지 관여
3. 웹 관련 스코프 : 웹 환경에서만 동작 / 프로토타입과 다르게 스프링이 해당 스코프의 종료시점까지 관리
- request : HTTP 요청이 들어오고 나갈 때까지 유지되는 스코프, 각 HTTP 요청마다 별도의 빈 인스턴스 생성 및 관리
- session : HTTP Session이 생성되고 종료될 때까지 유지되는 스코프
- application : 웹의 서블릿 컨텍스트와 같은 범위로 유지되는 스코프
▶ 싱글톤과 프로토타입의 차이
- 싱글톤 스코프의 빈을 조회하면 스프링 컨테이너는 항상 같은 인스턴스의 스프링 빈을 반환하지만, 프로토타입 스코프를 스프링 컨테이너에 조회하면 스프링 컨테이너는 항상 새로운 인스턴스를 생성해서 반환
- 스프링 컨테이너는 프로토타입 빈을 생성하고 의존관계 주입, 초기화까지만 처리하므로, 이후 스프링 컨테이너는 생성된 프로토타입 빈을 관리하지 않게 되며, 빈을 관리할 책임은 빈을 받은 클라이언트에게 돌아감. 따라서, @PreDestroy와 같은 종료 메소드를 호출할 수 없게 됨
▶ 싱글톤과 프로토타입을 함께 사용 시 문제점
→ 싱글톤 빈이 프로토타입 빈을 사용하게 됨
→ 그러나 싱글톤 빈은 생성 시점에만 의존관계 주입을 받기 때문에, 프로토타입 빈이 새로 생성되기는 하지만 싱글톤 빈과 함께 계속 유지될 수 없는 것이 문제
→ 사용자는 프로토타입 빈을 주입 시점에만 새로 생성하는 것이 아닌, 사용할 때마다 새로 생성하는 환경을 원하게 됨
▶ 싱글톤과 프로토타입을 함께 사용 시 Provider로 문제 해결
→ 가장 간단한 방법은 싱글톤 빈이 프로토타입을 사용할 때마다 스프링 컨테이너에 새로 요청하는 것
→ 의존관계 주입(DI) 대신 직접 필요한 의존관계를 찾는 Dependency Lookup(DL)(의존관계 조회) 방식 활용
→ 스프링의 애플리케이션 컨텍스트 전체를 주입받을 경우 스프링 컨테이너에 종속적인 코드가 되며, 단위 테스트가 어려워 짐
→ 필요한 기능은 지정한 프로토타입 빈을 컨테이너에서 대신 찾아주는 DL 정도의 무언가
→ 활용방법들
- ObjectFactory : 기능이 단순, 별도의 라이브러리 필요 없음, 스프링에 의존
- ObjectProvider : ObjectFactory상속, 옵션, 스트림 처리 등 편의기능 많음, 별도 라이브러리 필요 없음, 스프링에 의존
- JSR-330 Provider : 자바 표준 기술을 사용하는 방법, 기능이 get()메소드 하나, 별도의 라이브러리 필요, 자바 표준이므로 스프링이 아닌 다른 컨테이너에서도 사용 가능
=> 만에 하나 코드를 스프링이 아닌 다른 컨테이너에서 사용할 경우 JSR-330 사용
▶ 프로토타입 빈은 언제 사용할까?
프로토타입 빈 : 매번 사용할 때마다 의존관계 주입이 완료된 새로운 객체가 필요할 때
→ 실무에서 싱글톤 빈으로 대부분의 문제를 해결할 수 있기 때문에 프로토타입 빈의 사용은 매우 드물다.
→ 그러나 스프링의 핵심 원리 중 하나이기 때문에 반드시 숙지해둘 것
▶ 스코프와 프록시
- 프록시 설정 방법 : @Scope에 proxyMode = ScopedProxyMode.TARGET_CLASS 추가하기 (INTERFACES)
- 가짜 프록시 클래스를 만들어두고 HTTP request와 상관 없이 가짜 프록시 클래스를 다른 빈에 미리 주입
- Spring CGLIB라는 라이브러리로 내 클래스를 상속 받은 가짜 프록시 객체를 만들어서 주입
- 가짜 프록시 객체는 요청이 오면 그때 내부에서 진짜 빈을 요청하는 위임 로직이 들어있다.
- 가짜 프록시 객체는 원본 클래스를 상속받아서 만들어졌기 때문에, 이 객체를 사용하는 클라이언트 입장에서는 사실 원본인지 아닌지도 모르게 사용할 수 있다. (다형성의 힘)
- 싱글톤처럼 동작하며, request scope와 관계 없음
=> 프록시 객체 덕분에 클라이언트는 마치 싱글톤 빈을 사용하듯 편리하게 request scope를 사용할 수 있게 됨
=> 사실 Provider나 프록시나 핵심 아이디어는 진짜 객체 조회를 필요한 시점까지 지연처리한다는 점
=> 어노테이션 설정 변경만으로 원본 객체를 프록시 객체로 대체 가능 → 다형성과 DI 컨테이너의 가장 큰 장점
=> 웹 스코프가 아니어도 프록시는 사용 가능
=> 주의점 : 마치 싱글톤을 사용하는 것 같지만 다르게 동작하기 때문에 주의해서 사용할 것
'JVM > Spring' 카테고리의 다른 글
AOP의 간단한 개념들 (0) | 2021.08.23 |
---|---|
Spring Boot 핵심 개념들 (0) | 2021.08.23 |
빈 생명주기 콜백 (0) | 2021.03.25 |
ComponentScan과 의존관계 주입 방법에 대해서 (0) | 2021.03.24 |
싱글톤 컨테이너 (0) | 2021.03.24 |