본문 바로가기
개발자 공부 - 인프런 온라인 강의/스프링 핵심 원리 - 기본편

[섹션 9. 빈 스코프] 프로토타입 스코프 - 싱글톤 빈과 함께 사용시 문제점 / 인프런 김영한 스프링 핵심 원리 기본편

by easpop 2023. 10. 2.
728x90
반응형

이번 시간에는 프로토타입 스코프를 싱글톤 빈과 함께 사용할 때 생기는 문제점에 대해서 알아보았다.

 

스프링 컨테이너에 프로토타입 스코프의 빈을 요청하면 항상 새로운 객체 인스턴스를 생성해서 반환한다.

하지만 싱글톤 빈과 함께 사용할 때는 의도한대로 잘 작동하지 않는다.

 

먼저 스프링 컨테이너에 프로토타입 빈을 직접 요청하는 예제를 보자.

 

코드로 보기 위해 클래스를 생성해준다.

 

반응형

singletonClientUsePrototype 메소드를 생성하고, ClientBean을 받아서,

logic 메소드에서 프로토타입을 다른 클라이언트에서 2번 호출해준다.

그래서 같은 객체에서 count가 올라가는지, 아니면 다른 객체에서 count가 올라가는지 확인하는 코드를 짜준다.

 

30번째 라인에서, new 할 때 클라이언트 빈도 넣어주고 프로토타입 빈도 넣어주고,

2개를 다 컴포넌트 스캔을 해줘야 둘다 자동 빈 등록이 된다.

 

69번째 라인의 init 메소드에서는, 객체가 생성될 때 참조값을 보기 위해 this 를 콘솔에 찍어준다.

 

테스트를 돌려보면, 테스트가 통과되는 것을 확인할 수 있다.

결론적으로, 객체는 한번 생성이 되었고, 다른 클라이언트에서 호출했을 때, 같은 객체에서 카운트가 올라가는 것을 확인할 수 있다.

 

원리를 살펴보자면,

생성자를 만들때, prototype bean을 요청하면, 스프링 컨테이너 내부적으로 요청을 한다.

그럼 스프링 컨테이너가 프로토타입 빈을 만들어서, 위의 코드 사진 43번째 라인에 prototypeBean 객체에 주입해준다.

그렇기 때문에 생성시점에 주입이 되었기 때문에, 계속 같은 빈 객체를 쓰게 되는 것이다.

 

그래서 logic 메소드를 여러번 호출해도 prototypeBean은 이미 생성 시점에 주입이 된 같은 prototypeBean을 쓰게 된다.

그렇기 때문에, logic 메소드에서 count는 1이 아닌 2를 반환하게 된다.

 

 

만약 프로토타입 빈을 원래와 같이 로직을 호출할 때 마다 생성해서 쓰고 싶다면?

프로토타입 빈을 쓰는 이유는 계속 새로 만들어서 쓰고 싶은건데....

의도와는 다르게 싱글톤 빈으로 유지가 되게 된다.

 

프로토타입 빈을 주입 시점에만 새로 생성하는게 아니라, 사용할 때 마다 새로 생성해서 사용하길 원한다면,

약간 무식한 방법으로...ㅋㅋㅋㅋ 위와 같은 방법도 있다.

ApplicationContext를 주입받아서 getBean으로 프로토 타입 빈을 직접 받는 방법이다.

이렇게 되면, logic을 호출할 때 마다, 스프링 컨테이너에게 프로토타입을 요청하고,

그러면 스프링 컨테이너가 새로 생성해서 반환해줄 것이다.

 

 

 

정리하자면, 스프링은 일반적으로 싱글톤 빈을 사용하기 때문에, 싱글톤 빈이 프로토 타입 빈을 사용하게 된다.

그런데 싱글톤 빈은 생성 시점에만 의존관계를 주입받기 때문에, 프로토타입 빈이 새로 생성되기는 하지만,

싱글톤 빈과 함께 계속 유지되는 것이 문제다.

 

아마도 원하는 것이 이런 것을 아닐 것이다.

프로토타입 빈을 쓴다는 것 자체가, 계속 사용할 때 마다 새로 생성하기를 원할 것이다.

 

참고로 여러 빈에서 같은 프로토타입 빈을 주입받으면, 주입받는 시점에 각각 새로운 프로토타입 빈이 생성된다.

예를 들어서, clientA, clientB가 각각 의존관계 주입을 받으면 각각 다른 인스턴스의 프로토타입 빈을 주입받는다.

ex) clientA -> prototypeBean@x01

clientB -> prototypeBean@x02

물론 사용할 때 마다 새로 생성되는 것은 아니다.

728x90
반응형

댓글