te___ho
NO RULES
te___ho
전체 방문자
오늘
어제
  • 분류 전체보기 (88)
    • My project (27)
      • High Traffic Lab (3)
      • Nanaland in Jeju (8)
      • Univey (3)
      • inflearn_clone? (13)
    • Spring (19)
    • Network & CS (9)
    • Java (1)
    • Front_End (8)
    • Algorithm (11)
    • ETC (6)
    • Scribble (7)

인기 글

최근 글

티스토리

hELLO · Designed By 정상우.
te___ho

NO RULES

Spring

[Spring] 빈 스코프 (프로토타입)

2022. 8. 9. 17:59

 빈 스코프

 빈 스코프의 뜻을 강의 자료에서 가져오자면 빈이 존재할 수 있는 범위이다. 스프링 컨테이너가 언제까지 관리해주는지를

정한다고 생각하면 될 것 같다. 지금까지 사용한 싱글톤 (싱글톤 스코프)은 컨테이너가 생성되고 종료될 때까지 유지된다.

 스코프를 설정하는 방법은 @Bean 이나 @Component 위에 @Scope("xxx")를 작성해주면 된다. (꼭 위에 작성해야 된다는 게 아니라 그 위치라는 의미이다. 뭔 말인 줄 알지) 싱글톤은 default값이라 @Scope("singleton")을 굳이 작성해주지 않아도 된다.

 

 프로토타입

 포로토토입(prototype) 스코프는 요청이 들어올 때마다 새로운 빈을 생성한다. 클라이언트 4명이 요청을 하면 4개의 빈을 생성해서 각각 다른 빈을 반환한다. 또한 빈의 생성과 의존관계 주입까지만 관여한다. 빈을 만들고 세팅까지 마친 후 컨테이너에서 더 이상 관리를 해주지 않는다. 세팅은 빈을 생성한 후 의존관계 주입, 초기화(@PreConstruct 실행)까지만 처리해준다. 그러므로 @PreDestroy는 실행되지 않는다. 종료 메서드를 호출해야 한다면 클라이언트에서 책임을 져야 한다. 이때 프로토타입을 싱글톤과 같이 사용하면 예상치 못한 문제가 생긴다.

 

 싱글톤 스코프를 사용하고 PBean라는 프로토타입 빈을 주입받는 SBean 빈이 있다고 가정하자. SBean은 싱글톤이므로 스프링 컨테이너가 생성되는 시점에 생성, 의존관계 주입이 끝난다. 이때 PBean@01이 주입됐다. 클라이언트A가 SBean을 요청하여 사용했다. 이때 사용된 빈은 SBean과 주입된 PBean@01이다. 문제는 클라이언트 B가 SBean을 요청할 때이다. 싱글톤인 SBean은 같은 빈이 사용될 것이고 그렇다면 PBean은 PBean@02를 사용하게 될까?? 정답은 No. SBean이 생성 시에 PBean@01을 주입받았기 때문에 SBean을 사용할 시 계속 PBean@01을 사용하게 된다. 프로토타입은 요청이 들어올 때 생성되는 것이지 사용될 때마다 생성되는 것이 아니다.

 문제는 여기서 발생한다. prototype으로 주입을 받았다는 것은 사용할 때 마다 새로운 빈을 생성하고 싶었기 때문 아닐까???

 

 해결방법은 DL을 사용하는 것이다. 의존 관계를 주입 받는 것이 아니라 Lookup 조회하는 것이다. (스프링 컨테이너를 DI 받아 사용할 때마다 getBean 하는 방법이 있는데 스프링 컨테이너에 종속적인 코드가 되고 컨테이너 전체를 호출하긴 너무 헤비 하다.)

 

 ObjectProvider

@Autowired
  private ObjectProvider<PrototypeBean> prototypeBeanProvider;
  public int logic() {
      PrototypeBean prototypeBean = prototypeBeanProvider.getObject();
      prototypeBean.addCount();
      int count = prototypeBean.getCount();
      return count;
}

ObjectProvider <T>를 스프링 컨테이너에 올린다. 이건 빈을 직접적으로 생성한 상태가 아니다. 필요할 때마다 (사용할 때마다). getObject()로 bean을 불러오는 것이다. (음 이상하지만 예를 들면 우리가 사용하고 싶은 것이 물(water)이면 물을 컨테이너에 등록하는 게 아니라 정수기를 컨테이너에 등록하는 거다. 그래서 사용하고 싶을 때마다 냉수 버튼을 눌러서 (.getObject()) 사용하는 것이다.) ObjectProivder는 ObjectFactory를 상속해서 편의 기능을 추가하였다. 또한 스프링에 의존적이라는 특징이 있다.

 

 Provider

 Provider는 javax 라이브러리에 포함되어 있다. 

@Autowired
private Provider<PrototypeBean> provider;
  public int logic() {
      PrototypeBean prototypeBean = provider.get();
      prototypeBean.addCount();
      int count = prototypeBean.getCount();
      return count;
}

 별도의 라이브러리가 필요하고 자바 표준이어서 다른 컨테이너에서 사용할 수도 있다.

 

 (실무에서는 싱글톤으로 대부분 해결 가능하여 프로토타입을 사용하는 경우는 드물다고 한다...)

https://inf.run/NPt8

 

스프링 핵심 원리 - 기본편 - 인프런 | 강의

스프링 입문자가 예제를 만들어가면서 스프링의 핵심 원리를 이해하고, 스프링 기본기를 확실히 다질 수 있습니다., - 강의 소개 | 인프런...

www.inflearn.com

 

728x90
반응형
저작자표시 (새창열림)

'Spring' 카테고리의 다른 글

[Spring] Gradle vs Maven (빌드? 빌드 도구?)  (0) 2022.12.29
[Spring] 웹 스코프 (request) & 프록시  (2) 2022.08.11
[Spring] @Qualifier, @Primary & 빈 생명주기 콜백  (2) 2022.08.06
[Spring] 의존관계 자동 주입 방법 & 옵션 처리 & LOMBOK(롬복)  (0) 2022.08.01
[Spring] @ComponentScan & @Autowired (의존관계 자동 주입)  (2) 2022.07.26

    티스토리툴바