♪ 학습 내용
싱글톤 빈과 프로토타입 빈 충돌 시
* 싱글톤 빈과 프로토타입 빈 함께 사용시 문제
싱글톤 빈인 ClientBean이 생성자 주입으로 프로토타입 빈을 주입 받는 상황을 가정해보면
ClientBean은 싱글톤이기에 컨테이너에서 쭉 관리.
따라서 여러 고객이 ClientBean을 요청해도 같은 인스턴스를 반환해준다.
문제는 생성자 주입으로 프로토타입 빈과 의존관계를 맺기 때문에,
여러 고객이 요청한 ClientBean 이 의존하는 프로토타입 빈도 전부 같은 인스턴스이다.
빈 스코프가 프로토타입이면 매 요청시 새로운 빈을 반환해야 하는데 그게 깨져버린 상황 발생!
즉 주입 시전에 프로토타입 빈이 새로 생성되는 것이지, 요청마다 새로 생성되는 것이 아님.
원하는 건 싱글톤 빈에서도 해당 프로토타입 빈을 사용할 때 마다 매번 새로 생성하는 것.
근본적인 해결 방법은 프로토타입 빈을 생성자 주입 받지 않고, 사용때마다 매번 컨테이너에 조회, 요청하는 것.
위 코드에서 주입 받지 않고 매번 컨테이너에 요청하여 새로 반환받으려면 생성자, 필드 선언 없애고
다음과 같이 logic() 메서드를 수정해야할 것이다
@Autowired
private ApplicationContext ac;
public int logic(){
//logic메서드 실행마다 프로토타입 빈 조회 => 매번 새로 생성
PrototypeBean prototypeBean = ac.getBean(PrototypeBean.class);
prototypeBean.addCount();
int count = prototypeBean.getCount();
return count;
}
이렇게 실행해보니 매번 반환되는 프로토타입 빈이 각각 다른 인스턴스인걸 확인할 수 있었음.
의존관계를 외부에서 주입(DI) 받지 않고 직접 찾는 것을 Dependency Lookup(DL), 의존관계 조회(탐색)
지금 위 코드는 정말 권장하지 않는 방식
앞으로는 우리 대신 DL, 의존관계 탐색해줄 무언가를 공부
그렇게 되면 결과는 동일하면서 DL관련 코드도 간단해질 것이다.
* ObjectProvider
해당 빈을 컨테이너에서 찾아주는 DL서비스 제공한다.
getObject()를 호출 시, 스프링 컨테이너를 통해 해당 빈을 찾음 == 호출마다 프로토타입 빈 새로 생성한다
외에도 다양한 편리한 기능이 많다. 하지만 여전히 스프링에 의존적
* JSR-330 Provider
이 방법은 자바 표준으로 스프링에 의존하지 않음!
만약 해당 코드를 스프링 컨테이너가 아닌 다른 컨테이너에서도 사용해야한다면 ObjectProvider가 아니라 이것을 사용
(물론 그럴 일은 거의 없다)
기능은 get() 메서드 하나로 매우 단순하다!!
단점으로는 별도의 라이브러리 필요.
해당 방법 사용하기 위해서 gradle.build에 직접 library를 추가해줬다.
&& 해당 방법들은 프로토타입 뿐만 아니라 DL 필요한 상황에서 언제든 사용 &&
? 궁금증에 대한 답변 - 프로토타입 빈은 언제 사용할까?
바로 이전 학습 때 싱글톤과 전혀 다른 방식으로 행동하는 프로토타입 빈을 보면서
과연 언제 어떤 용도로 사용할 지 궁금했었는데 이번 학습에서 답을 얻게 되었다.
프로토타입은 기능 그대로 사용할 때 마다 의존관계 주입 완료된 새로운 객체가 필요할때 사용하면 됨.
하지만 실무에서는 싱글톤으로 대부분 해결 가능하기에 사용할 일이 거의 없다는 것이 답변
♪ 다음 학습 내용
웹 스코프
'Dev > Spring' 카테고리의 다른 글
[Spring MVC 1] 웹 애플리케이션의 이해 (0) | 2023.01.07 |
---|---|
[Spring 기본] 빈 스코프 (3) (0) | 2022.12.18 |
[Spring 기본] 빈 스코프 (1) (0) | 2022.11.25 |
[Spring 기본] 빈 생명주기 콜백 (0) | 2022.11.22 |
[Spring 기본] 의존관계 자동 주입 (4) (0) | 2022.11.20 |
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!