Untitled

clientBean 은 싱글톤이므로 보통 스프링 컨테이너 생성 시점에 함께 생성되고 의존관계 주입도 발생한다.

  1. clientBean 은 의존관계 자동 주입을 사용한다. 주입 시점에 스프링 컨테이너에 프로토타입 빈을 요청한다.
  2. 스프링 컨테이너는 프로토타입 빈을 생성해서 clientBean 에 반환한다. 프로토타입 빈의 count 필드 값은 0 이다.

이제 clientBean 은 프로토타입 빈(참조값)을 내부 필드에 보관한다.

Untitled

클라이언트 A 는 clientBean 을 스프링 컨테이너에 요청해서 받는다. 싱글톤이므로 항상 같은 clientBean 이 반환된다.

  1. 클라이언트 A 는 clientBean.logic() 을 호출한다.
  2. clientBean 은 prototypeBean 의 addCount() 를 호출해서 프로토타입 빈의 count 를 증가시킨다. count 값이 1 이 된다.

Untitled

클라이언트 B 는 clientBean 을 스프링 컨테이너에 요청해서 받는다. 싱글톤이므로 항상 같은 clientBean 이 반환된다. 하지만 clientBean 이 내부에 가지고 있는 프로토타입 빈은 이미 과거에 주입이 끝난 빈이다. 주입 시점에 스프링 컨테이너에 요청해서 프로토타입 빈이 새로 생성된 것이지, 사용할 때마다 새로 생성되는 것이 아니다.

  1. 클라이언트 B 는 clientBean.logic() 을 호출한다.
  2. clientBean 은 prototypeBean 의 addCount() 를 호출해서 프로토타입 빈의 count 를 증가시킨다. count 값은 2 가 된다.

정리

프로토타입 빈은 호출할 때마다 새로 생성되는 것이 아닌 일반 객체와 동일한 생명주기를 가진 빈이라고 생각하면 된다. 빈을 만드는 주체가 스프링 컨테이너이기 때문에 스프링 컨테이너에서 새로 호출할 때 새로운 빈이 생성될 뿐, 이미 호출된 빈은 일반 객체와 동일한 생명주기를 가진다. (생성된 후 오랜 시간이 지나 더 이상 참조되지 않으면 GC 에 의해 제거된다.)

참고

여러 빈에서 같은 프로토타입 빈을 주입받으면 주입받는 시점에 각각 새로운 프로토타입 빈이 생성된다. 예를 들어서 clientA, clientB 가 각각 의존관계 주입을 받으면 각각 다른 인스턴스의 프로토타입 빈을 주입받는다.

clientA → prototypeBean@x01

clientB → prototypeBean@x02