본문 바로가기
Back-end/Spring 개념

16. Bean Scope에 대하여

by devraphy 2022. 2. 17.

0. 개요

- 이전 포스팅에서 Spring Bean의 생명주기에 대해 배웠다.

- Spring은 Spring Continer의 시작과 종료까지의 큰 흐름 안에 다양한 생명주기를 가진 Bean을 제공한다.

- 이번 포스팅에서는 다양한 Bean의 생명주기에 대해서 알아보자. 


1. Bean Scope

a) Bean Scope란? 

- Spring에는 다양한 종류의 Bean이 존재한다.

- Bean의 역할과 사용 목적에 따라 Bean의 종류가 달라지는데, 이에 따라 다양한 생명주기를 갖는다.

- Bean의 종류에 따라 달라지는 Bean 생명주기를 Bean Scope라고 부른다.  

 

- 모든 Bean이 애플리케이션이 종료될 때까지 Spring Container에 의해 관리되는 것이 아니다. 

- 즉, Scope는 Bean이 어느 시점까지 Spring Container에 의해 관리되는지를 정의한 것이다. 

 

b) Bean Scope의 종류

- Spring은 다음과 같은 다양한 생명주기를 가진 Bean을 제공한다. 

   - Singleton Scope

   - Prototype Scope

   - Web Scope


2. Bean Scope의 종류와 특징

a) Singleton Scope

- 싱글톤은 Spring에서 기본적으로 Bean에게 부여하는 Scope다.

- Spring Container의 시작부터 종료까지 유지되는 가장 넓은 범위의 scope다.

- default로 제공되는 값이기 때문에, 따로 명시할 필요는 없으나, 다음과 같이 명시할 수 있다.

@Scope("sigleton")

- Singleton Scope를 가지는 Bean은 Spring Container가 종료될 때까지 Spring Container에 의해 관리된다. 

- 그러므로 Client가 Bean을 요청할 때마다 동일한 Bean을 반환한다.

- 즉, 최초에 생성된 하나의 Bean을 계속해서 사용한다.  

 

b) Prototype Scope

- 프로토타입은 Bean이 생성되고 DI가 주입된 후 Spring Container의 관리를 받지 않는다. 

- 프로토타입은 매우 짧은 범위를 가지는 Bean scope다.

@Scope("prototype")

- 프로토타입 Scope를 가지는 Bean은 Spring Container에 의해 생성되고 반환된 후, Bean의 관리책임을 Client에게 양도한다. 

- 그러므로 Client가 Bean을 요청할 때마다 새로운 Bean을 생성하여 반환한다.

- Bean 반환 후 Bean의 관리책임을 Client가 수행하므로, Client가 Bean 생명주기의 소멸 메서드를 호출해야 한다.

 

c) Web Scope

- 웹 작업을 처리하기 위해 사용하는 Bean에 부여되는 scope다.

- 웹 스코프는 다음과 같은 종류를 갖는다.

   - Request Scope: HTTP Request가 처리될 때까지 유지된다. 

   - Session Scope: 웹 세션이 생성되고 종료될 때까지 유지된다. HTTP Session과 동일한 생명주기를 갖는다. 

   - Application Scope: 웹 서블릿 콘텍스트와 동일한 범위로 유지된다. 


3. Singleton Bean과 Prototype Bean

- 서로 다른 Scope을 가진 Bean을 이용하여 의존관계를 형성하면 어떻게 될까? 

- 아마도 서로 다른 생명주기로 인해 문제가 발생할 것이다. 

- 어떤 문제인지, 그 해결책은 무엇인지 알아보자. 

 

* 실무에서는 대부분 싱글톤 Bean을 사용하여 개발한다. 그러므로 프로토타입 Bean을 사용할 일은 매우 드물다. 

 

a) 문제점 (SB = Singleton Bean, PB = Prototype Bean)

- 예를 들어, SB에서 PB을 주입받아 사용한다고 해보자.

- SB은 Spring Container가 종료되기까지 하나의 객체를 계속해서 사용한다.

- 즉, 주입받은 PB를 계속해서 사용하게 된다. 

 

- PB는 요청될 때마다 Spring Container가 새로운 PB를 생성한다.

- 그러나 SB와 함께 사용하면 PB의 특성을 사용하지 못하게 된다. 

 

b) 해결책 - Dependency Lookup

- 이 문제의 해결방안은 SB 내부에서 Spring Container에게 PB를 달라고 요청하는 것이다. 

- 즉, DI를 주입받는 것이 아니라 필요한 DI 대상을 직접 요청하는 DL을 수행하는 것이다.

 

- 그러나 여기에는 한 가지 문제점이 있다. 바로 SRP를 위배한다는 것이다.

- 더불어, SB에서 Spring Container에게 PB를 요청하므로 코드 자체가 Spring Container에게 의존적이다.

- 그렇다면 이 과정(DL)을 외부에서 누군가 대신해주면 되지 않을까? 


4. Dependency Lookup

a) Object Factory, Object Provider

- Object Factory와 Object Provider 모두 DL을 수행하는 역할을 가진 인터페이스다. 

- Object Provider는 Object Factory를 상속받은 인터페이스로, 더 많은 기능을 가진다. 

 

- 핵심은 DL을 외부에서 대신 수행할 수 있다는 것이다. 

- 그러나 이는 Spring에서 제공하는 기능으로, Spring에 종속적인 코드라는 점은 동일하다. 

 

b) JSR-330 Provider

- JSR(Java Specification Request)은 Java 표준을 의미한다.

- JSR에서도 Provider 라이브러리를 제공하며, Gradle에 추가하여 사용할 수 있다.

- JSR에서 제공하는 Provider에는 get() 메서드 하나만 존재하며, DL 기능을 수행한다.

- Java 표준이므로 Spring에 종속적이라는 문제점을 해결한다. 

package javax.inject;
public interface Provider<T> {
  T get();
}

5. Web Scope

- 웹 scope는 웹 환경에서만 동작한다.

- 웹 scope는 스프링이 해당 scope의 종료 시점까지 관리한다. 

 

a) Web Scope와 DL 

- web scope는 왜 DL 기능을 필요로 할까? 

 

- HTTP Request를 Bean으로 사용하는 코드를 작성한 경우, 빌드 시점에서 오류가 발생한다.

- 그 이유는 아직 HTTP Request가 서버에 들어오지 않아 Request 객체가 존재하지 않으나,

   Request 객체를 사용하여 의존 관계를 형성하기 때문이다.

 

- 그렇다면 인위적으로 외부에서 Request 객체를 만들어 주입해주면 되지 않을까? 

- Request가 사용하는 DL 기능을 알아보자. 

 

b) @Scope 옵션 - Proxy

- @Scope에는 proxyMode라는 옵션이 있다.

@Scope(value = "request", proxyMode = ScopeProxyMode.TARGET_CLASS)
              // scope                 // 적용 대상의 타입을 명시

 

- 이는 가짜 request 객체를 만들어 주입시켜주는 방식으로,

   Spring이 최초 빌드 시점에서 의존관계 형성에 필요한 request 객체를 대신하기 위함이다. 

   → 실제로 최초에 생성되는 가짜 request 객체는 CGLIB에 의하여 복사된 객체다. 

 

- 빌드 시점에서는 가짜 request 객체를 사용하지만, 실제로 HTTP 요청이 들어오면 실제 Request 객체가 생성 및 사용된다.

  → 이를 Spring의 위임 기능이라고 한다. 

 

- Spring 위임 기능이라 하면 Spring Bean 자체가 가짜에서 진짜로 변경된다고 생각할 수 있다.

  → 실제로는 request의 생명주기 동안 가짜 객체가 계속 사용되는데, 가짜 객체는 진짜 객체에 접근할 수 있다. 

  → 가짜 객체가 진짜 request 객체를 호출한다. 


6. 결론

- 지금까지 Bean이 가질 수 있는 다양한 Scope에 대해 배우면서,

   Bean Scope에 따라 발생하는 문제와 해결방법을 알아보았다. 

 

- Scope에 따라 Bean Lifecycle이 다르므로, 이 점을 유의하여 사용하도록 하자.

 

- 실무에서는 사실 Singleton Scope 외의 Scope을 잘 사용하지 않는다고 한다. 

- 그러므로 Singleton Bean/Scope을 잘 사용하자.  

댓글