본문 바로가기

스터디/소연

스프링 Bean의 Scope에 대해서 설명해주세요.

Scope: 빈이 존재할 수 있는 범위

스코프 종류  
Singleton 기본값
하나의 스프링 컨테이너에 한 개만 사용 가능
스프링 컨테이너의 시작과 종료까지 유지(가장 넓은 범위의 스코프)
Prototype 매번 사용될 때마다 빈을 생성해서 사용
빈의 생성과 의존관계 주입까지만 관여
매우 짧은 범위의 스코프
Request 웹 요청이 들어오고 나갈 때까지 빈을 사용
web-aware context에서만 사용 가능
Session 웹 세션이 생성되고 종료될 때까지 하나의 빈을 사용
web-aware context에서만 사용 가능
Application 웹의 서블릿 컨텍스트와 같은 범위로 유지되는 스코프
web-aware context에서만 사용 가능
Websocket Websocket 라이프사이클 안에서 한 개의 빈만 사용
web-aware context에서만 사용 가능

 

사용법

@Component
@Scope(value = "prototype")
public class ProtoType {
}

자동 등록

컴포넌트 등록하면서 @Scope 어노테이션 사용

value에 원하는 스코프 종류를 적어주면 됨

 

@Scope("prototype")
@Bean
PrototypeBean HelloBean() {
    return new HelloBean();
}

수동등록

 

싱글톤 빈과 함께 사용시 문제점

 

싱글톤 스코프의 빈이 프로토타입 빈을 주입받으면 싱글톤의 프로토타입 빈은 매번 바뀌지 않고 같은 빈이 쓰임

singleton 빈 안에 있는 prototype 빈도 처음 주입된 채로 그대로 사용되기 때문

 

- 해결방법 1(스프링 컨테이너에 새로 요청)

 @Autowired
  private ApplicationContext ac;
  public int logic() {
      PrototypeBean prototypeBean = ac.getBean(PrototypeBean.class); //ac.getBean()을 통해 새로운 프로토타입 빈 생성
      prototypeBean.addCount();
      int count = prototypeBean.getCount();
      return count;
 }

싱글톤 빈이 프로토타입을 사용할 때마다 스프링 컨테이너에 새로 요청

 

- 해결방법 2(ObjectProvider - 지정한 빈을 컨테이너에서 대신 찾아줌)

@Autowired
  private ObjectProvider<PrototypeBean> prototypeBeanProvider;
  public int logic() {
		//새로운 프로토타입 빈 생성 > 스프링 컨테이너를 통해 해당 빈을 찾아서 반환
      PrototypeBean prototypeBean = prototypeBeanProvider.getObject();
      prototypeBean.addCount();
      int count = prototypeBean.getCount();
      return count;
}

스프링에 의존하기 때문에 다른 컨테이너에서도 사용할 수는 없음

 

-해결방법 3(Provider - 자바 표준을 이용하여 지정한 빈을 컨테이너에서 대신 찾아줌)

//implementation 'javax.inject:javax.inject:1' gradle 추가 필수

@Autowired
private Provider<PrototypeBean> provider;

public int logic() {
    PrototypeBean prototypeBean = provider.get();
    prototypeBean.addCount();
    int count = prototypeBean.getCount();
    return count;
}