✔ 스프링이 지원하는 다양한 스코프
✔ 스코프 지정 방법 @Scope("스코프 종류 소문자")
@Scope("prototype")
@Component
public class HelloBean {}
@Scope("prototype")
@Bean
PrototypeBean HelloBean() {
return new HelloBean();
}
싱글톤 스코프 빈은 조회하면 항상 같은 인스턴스의 스프링 빈을 반환한다.
스프링 컨테이너에 객체 생성하고 그 객체 하나를 주고 받는 것이다.
✔ 싱글톤 빈과 프로토타입 스코프를 함께 사용하는 경우
static class ClientBean {
private final PrototypeBean prototypeBean;
@Autowired
public ClientBean(PrototypeBean prototypeBean) {
this.prototypeBean = prototypeBean;
}
public int logic() {
prototypeBean.addCount();
int count = prototypeBean.getCount();
return count;
}
}
@Scope("prototype")
static class PrototypeBean {
private int count = 0;
public void addCount() {
count++;
...
}
포로토타입 스코프 빈은 싱글톤 빈을 생성하고 의존관계 주입하는 시점에 생기게 된다.
싱글톤 타입의 스코프 빈은 한번 생성되는 것이기 때문에 의존관계 주입 또한 한번 일어나게 된다. 따라서 프르토타입 스코프 빈 또한 한번 생성되는 것이고 여러 클라이언트가 프로토타입을 요청할 경우 다른 프로토타입의 빈을 반환하는 것이 아니라 같은 포로토타입 빈을 반환하게 된다.
이는 개발자나 사용자가 의도한 바가 아니기 때문에
싱글톤 빈을 하나 생성하고
프로토타입 빈은 클라이언트가 요청할 때마다 생성될 수 있도록 수정하도록 하자.
✔️ 스프링 컨테이너에 싱글톤 빈이 프로토타입을 요청할 때마다 새로운 프로토타입 빈을 생성
static class ClientBean {
@Autowired
private ApplicationContext ac;
public int logic() {
PrototypeBean prototypeBean = ac.getBean(PrototypeBean.class);
prototypeBean.addCount();
int count = prototypeBean.getCount();
return count;
}
}
@Scope("prototype")
static class PrototypeBean {
private int count = 0;
...
}
위를 보면 싱글톤 빈의 생성자가 프로토타입의 빈을 생성하도록 의존관계를 맺고 있는 것이 아니라 하나의 싱글톤 빈 자체가 스프링 컨테이너를 하나 만들어 놓고 요청이 들어올 때마다 여기에 프로토타입 빈을 생성하고 반환하도록 만들어 놓았다.
의존관계를 맺도록 주입하는 것이 아니라 필요한 의존관계를 찾는 것은 Dependency Lookup 의존관계 조회(탐색)이라고 한다.
그러나 이렇게 스프링 애플리케이션 컨텍스트 전체를 주입받게 되면 스프링 컨테이너에 종속적이 코드
따라서 스프링에 종속적이지 않으면 DL의 기능을 하는 무언가가 필요하다
✔️ ObjectFactory, ObjectProvider
지정할 빈을 컨테이너에서 대신 찾아주는 DL 서비스
ObjectFactory: 구버전, 기능이 단순, 별도의 라이브러리 필요 없음, 스프링에 의존
ObjectProvider : 신버전, 상속, 옵션, 스트림 처리 등 편의 기능, 별도의 라이브러리 필요 없음, 스프링에 의존
static class ClientBean {
@Autowired
private ObjectProvider<PrototypeBean> prototypeBeanProvider;
public int logic() {
PrototypeBean prototypeBean = prototypeBeanProvider.getObject();
prototypeBean.addCount();
int count = prototypeBean.getCount();
return count;
}
}
prototypeBeanProvider.getObject() : 항상 새로운 프로토타입 빈을 생성
-> objetProvider은 getObject를 호출해서 내부 스프링 컨테이너를 통해 해당 빈을 찾음(DL)
스프링이 제공하는 기능 사용-> 기능이 단순하므로 단위테스트 훨씬 쉬어짐
하지만 그래도 스프링에 의존
✔️JSR-330 Provider
package javax.inject;
public interface Provider<T> {
T get();
}
//implementation 'javax.inject:javax.inject:1' gradle 추가 필수
static class ClientBean {
@Autowired
private Provider<PrototypeBean> provider;
public int logic() {
PrototypeBean prototypeBean = provider.get();
prototypeBean.addCount();
int count = prototypeBean.getCount();
return count;
}
Provider.get()을 통해서 새로운 프로토타입 빈 생성
get()메서드 하나로 기능이 매우 다양하며
별도의 라이브러리 필요 없음
자바 표준->스프링이 아닌 다른 컨테이너에서도 사용 가능
✔️ 웹 스코프 종류
✔️ Request 스코프