[Spring] Prototype

김형진·2023년 3월 31일
0

스프링 강의를 듣다보니 이전에 실무에서 한 번 사용해보았던 Prototype에 대한 내용을 다시 접하게 되었다.

당시 여러개의 프로메테우스의 자원을 수집할 때, 싱글톤 객체를 통해 자원수집이 이뤄지면 디버깅하기 까다롭다는 팀장님의 말씀에 각 프로메테우스의 정보를 담은 프로토타입 수집 객체를 사용하게 되었다.
어차피 동시에 수집되지 않고 순차적으로 진행되기 때문에 로그만 잘 찍어도 굳이 프로토타입으로 쓸 필요는 없을 것 같았지만,,,
이 때가 아니면 언제 써보나 싶기도 해 군말없이 따랐다.

스프링 스코프에는 여섯 종류가 있다.

1. singleton
2. prototype
3. session
4. request
5. websocket
6. application

이 중 프로토타입은 싱글톤처럼 Spring Container에서 필요한 의존주입을 해주고 인스턴스를 생성해주지만, 싱글톤과는 다르게 하나가 아닌 여러개가 생성될 수 있으며 생성 이후에는 스프링에서 관리해주지 않는다.

다시 말해, 의존주입과 초기화 메소드까지는 스프링에서 실행해주지만
사용자에게 넘겨준 이후에는 스프링에서 관리하지 않기 때문에 종료 메소드 같은 것은 자동으로 실행되지 않는다.

특징만 살펴보면 다른 여러 객체에 의존하는 객체의 인스턴스를 여럿 생성해야 하는 경우 유용하겠지만,, 그런 상황이 실제로 얼마나 일어날까 싶다. 웬만한 경우에는 싱글톤으로도 해결이 되기 때문이다.

컨테이너로부터 Prototype 빈을 넘겨받는 방법에는 여러가지가 있는데,

  1. 스프링 컨테이너(ApplicationContext)로부터 직접 getBean하는 방법
private final ApplicationContext ac; // 의존주입

public void testGetBean(){
	TestBean tb = ac.getBean(TestBean.class) // TestBean : 프로토 타입으로 관리되는 빈
}
  1. ObjectProvider(ObjectFactory)로부터 DL하는 법
private final ObjectProjvider<TestBean> provider; // 의존주입

public void testGetBean(){
	TestBean tb = provider.getObject()
}
  1. java 표준의 라이브러리에서 제공되는 Provider를 통해 DL하는 법
private final Provider<TestBean> provider; // 의존주입

public void testGetBean(){
	TestBean tb = provider.get()
}

DL(Dependency Lookup)이란, 스프링에서 필요한 의존을 주입하는 것과 비교되는 개념으로 필요한 의존을 직접 찾는다는 것을 말한다.
'프로토타입 빈도 스프링에서 의존주입까진 해주는데 이게 왜 DI랑 비교되는 개념이지?'
설명이 애매해 헷갈릴 소지가 있는데, 위의 예제코드에서처럼 그냥 TestBean을 스프링으로부터 의존주입 받지 않고 직접 찾는 행위를 DL이라 하는 것이다.

1번의 경우 너무 무거우면서 스프링의존적이기 때문에 권장되지 않는다고 한다.

그렇다면 2번과 3번 중 하나를 사용하게 될텐데,

2번의 ObjectProvider를 사용하는 경우 별도의 처리 없이 provider를 스프링으로부터 바로 의존주입받아 사용하면 되기 때문에 편리하다는 장점이 있다. 그러나 ObjectProvider의 경우 Spring에서 직접 제공하기 때문에 Spring의존적이게 된다는 단점이 있다.

3번의 Provider는 자바 표준이지만 library dependency를 추가해야 한다는 치명적인 단점이 있다. 어려운 일은 아니지만 프로토타입 하나 때문에 의존을 추가하는 것은 마음이 불편한 일이 아닐 수 없다.

아마 Prototype을 써야 한다면 일반적으로는 ObjectProvider를 쓰게 될 것이다.
스프링 의존적이긴 하지만, 스프링이 아닌 컨테이너를 사용할 일은 거의 없기에...

profile
히히

0개의 댓글