본문 바로가기
Spring

프로토타입 빈(Prototype Bean)

qbang 2021. 10. 9.

개요

스프링의 빈은 기본적으로 싱글톤으로 만들어진다. 하나의 빈 오브젝트에 동시에 여러 스레드가 접근하기 때문에 상태 값을 인스턴스 변수에 저장해두지 않고, 의존관계에 있는 빈에 대한 레퍼런스나 읽기전용 값만 저장해둔다.

그렇다면 빈을 싱글톤이 아닌 방법으로 만들 때는 어떻게 해야 할까? 싱글톤이 아닌 빈은 프로토타입 빈과 스코프 빈으로 나눌 수 있다.(싱글톤, 프로토타입도 스코프의 한 종류이다)

 

스코프(Scope)

존재할 수 있는 범위를 가리키고 빈 스코프는 빈 오브젝트가 만들어져서 존재할 수 있는 범위다.

싱글톤 스코프는 단일 컨테이너 구조에서 컨테이너가 존재한느 범위와 싱글톤이 존재하는 범위가 일치하기 때문에 컨테이너 스코프라고도 부른다.

 

프로토타입 스코프

싱글톤 스코프는 컨텍스트당 하나의 오브젝트만 만들어지기 때문에 해당 빈을 여러 개의 빈에서 DI 하더라도 매번 동일한 오브젝트가 주입된다. 싱글톤으로 설정된 빈은 DI이든 DL이든 상관없이 매번 같은 오브젝트가 사용된다.

싱글톤 대신 프로토타입 스코프로 빈을 선언하면 컨테이너에게 빈을 요청할 때마다 매번 새로운 오브젝트를 생성해준다. 

 

프로토타입 빈의 생명주기와 종속성

스프링에서 빈은 생성, 의존관계 주입, 초기화, DI 및 DL을 통한 사용, 제거까지 모든 오브젝트의 생명주기를 컨테이너가 관리한다.

하지만 프로토타입 빈은 IoC의 기본 원칙을 따르지 않는다. 프로토타입 스코프 빈은 요청이 있을 때마다 컨테이너가 생성, 초기화, DI까지 해주기도 하지만 빈을 제공하고서부터는 더 이상 빈 오브젝트를 관리하지 않는다. 따라서 DL을 통해 오브젝트를 가져간 코드나 DI로 주입받은 다른 빈이 사실상 빈 오브젝트를 관리하게 된다. 

따라서 프로토타입 빈은 해당 빈을 주입받은 오브젝트에 종속적이다. 프로토타입 빈을 주입받은 빈이 싱글톤이라면, 이 빈에 주입된 프로토타입 빈도 역시 싱글톤 생명주기를 따라 유지된다. DL 방식으로 getBean( ) 메서드를 통해 프로토타입 빈을 요청했다면, 요청한 코드가 유지되는 만큼 빈 오브젝트가 존재할 것이다.

 

프로토타입 빈의 용도

서버가 요청에 따라 독립적으로 오브젝트를 관리해야 하는 경우는 DO나 DTO를 new 키워드로 생성하고 파라미터로 전달해서 사용한다. 사용자의 요청별로 독립적인 정보나 작업 상태를 저장하려면 new 키워드나 팩토리를 이용해 코드 안에서 직접 오브젝트를 만들면 된다.

하지만 사용자의 요청에 따라 매번 독립적인 오브젝트를 만들어야 하는데, 새롭게 만들어지는 오브젝트가 컨테이너의 빈을 사용해야 하는 경우, 즉 DI가 필요한 오브젝트에서 프로토타입 빈을 유용하게 쓸 수 있다. 프로토타입 빈은 오브젝트 생성과 DI까지 마친 후 컨테이너가 돌려준다.

@Autowired ApplicationContext context; //타입에 의한 DI를 이용해 애플리케이션 컨텍스트를 받아둔다

public void serviceRequestFormSubmit(HttpServletRequest req){
    // new 대신 프로토타입 빈을 콘테이너에 요청해서 새로운 오브젝트를 가져온다
    ServiceRequest serviceRequest = this.context.getBean(ServiceRequest.class);
    serviceRequest.setCustomerNo(req.getParameter("custno"));
    ...
}

위처럼 애플리케이션 컨텍스트를 받아두고, new 대신 프로토타입 빈을 컨테이너에 요청해서 새로운 오브젝트를 가져올 수 있다. 해당 방법을 통해 매번 새롭게 오브젝트를 만들어야 하면서도 DI가 필요한 클래스(ServiceRequest)를 사용할 수 있다. 

 

본 게시글은 토비의 스프링 1.3 프로토타입과 스코프 내용을 바탕으로 작성되었습니다.

'Spring' 카테고리의 다른 글

JPA 복합키 사용 방법  (0) 2021.10.14
스프링에서 마이바티스(Mybatis) 사용하기  (0) 2021.10.13
JSON vs XML  (0) 2021.10.03
마이바티스(MyBatis)  (0) 2021.10.01
Spring Project 시작하기  (0) 2021.09.24

댓글