Spring Framework에서 @Scope 어노테이션은 스프링 빈(Bean)의 범위(Scope) 를 지정하는 데 사용됩니다. 기본적으로 빈은 싱글톤(Singleton)으로 생성되지만, @Scope를 사용하면 요청할 때마다 새로운 인스턴스를 생성하거나 특정 컨텍스트 내에서 유지되도록 조정할 수 있습니다.
1. @Scope 기본 개념
@Scope는 빈이 생성되고 관리되는 방식을 정의하는 어노테이션으로, 빈의 생명주기를 결정합니다. Spring에서는 여러 가지 범위를 지원하며, 가장 많이 사용되는 범위는 다음과 같습니다:
스코프 유형 설명
| singleton (기본값) | 애플리케이션 전체에서 단 하나의 인스턴스만 생성 |
| prototype | 요청할 때마다 새로운 인스턴스를 생성 |
| request | HTTP 요청이 있을 때마다 새로운 인스턴스를 생성 (웹 환경) |
| session | 사용자 세션별로 하나의 인스턴스 유지 (웹 환경) |
| application | 애플리케이션 컨텍스트 범위에서 하나의 인스턴스 유지 (웹 환경) |
| websocket | 웹소켓 세션별로 하나의 인스턴스 유지 (웹 환경) |
2. @Scope 사용 방법
(1) 싱글톤(Singleton) 스코프 (기본값)
Spring 빈의 기본 스코프는 singleton으로, 한 번만 생성되고 애플리케이션이 종료될 때까지 유지됩니다.
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component
@Scope("singleton") // 기본값, 생략 가능
public class SingletonBean {
public SingletonBean() {
System.out.println("SingletonBean 인스턴스 생성");
}
}
📌 동일한 빈을 여러 번 주입해도 항상 같은 인스턴스를 반환합니다.
(2) 프로토타입(Prototype) 스코프
prototype 스코프를 사용하면, 빈이 주입될 때마다 새로운 인스턴스가 생성됩니다.
@Component
@Scope("prototype")
public class PrototypeBean {
public PrototypeBean() {
System.out.println("PrototypeBean 인스턴스 생성");
}
}
📌 매번 새로운 객체가 생성되므로, 상태를 가지는 객체를 사용할 때 유용합니다.
✅ 싱글톤 빈에서 프로토타입 빈을 주입할 때 주의점
- 싱글톤 빈이 프로토타입 빈을 주입받으면, 프로토타입 빈은 최초 1회만 생성되며 동일한 객체가 재사용됩니다.
- 이를 해결하려면 ObjectFactory 또는 Provider를 사용할 수 있습니다.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Lookup;
import org.springframework.stereotype.Component;
@Component
public class SingletonService {
@Autowired
private PrototypeBean prototypeBean; // 항상 같은 인스턴스 사용됨
}
해결 방법: ObjectProvider 사용하기
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.stereotype.Component;
@Component
public class SingletonService {
private final ObjectProvider<PrototypeBean> prototypeBeanProvider;
@Autowired
public SingletonService(ObjectProvider<PrototypeBean> prototypeBeanProvider) {
this.prototypeBeanProvider = prototypeBeanProvider;
}
public void usePrototypeBean() {
PrototypeBean prototypeBean = prototypeBeanProvider.getObject();
System.out.println("PrototypeBean 사용");
}
}
3. 웹 환경에서의 스코프
(1) Request 스코프 (HTTP 요청별 새로운 인스턴스)
웹 애플리케이션에서 @Scope("request")를 사용하면 HTTP 요청이 발생할 때마다 새로운 인스턴스를 생성합니다.
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component
@Scope("request")
public class RequestBean {
public RequestBean() {
System.out.println("RequestBean 인스턴스 생성");
}
}
📌 사용자가 새로운 요청을 보낼 때마다 새로운 객체가 생성됩니다.
(2) Session 스코프 (사용자 세션별 인스턴스 유지)
사용자 세션이 유지되는 동안 하나의 인스턴스를 공유합니다.
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component
@Scope("session")
public class SessionBean {
public SessionBean() {
System.out.println("SessionBean 인스턴스 생성");
}
}
📌 동일한 사용자가 요청하는 동안 같은 인스턴스를 재사용합니다.
(3) Application 스코프 (애플리케이션 내에서 하나의 인스턴스 유지)
애플리케이션 전체에서 하나의 인스턴스를 공유합니다.
@Component
@Scope("application")
public class ApplicationBean {
public ApplicationBean() {
System.out.println("ApplicationBean 인스턴스 생성");
}
}
📌 서버가 종료될 때까지 하나의 객체만 유지됩니다.
4. @Scope를 사용할 때의 고려 사항
✅ 언제 singleton을 사용할까?
- 대부분의 서비스(Service) 계층 빈은 싱글톤으로 유지하는 것이 적절합니다.
- 상태를 가지지 않는 빈이거나, 여러 요청 간 공유되어도 문제가 없는 경우 사용합니다.
✅ 언제 prototype을 사용할까?
- 각 요청마다 새로운 인스턴스를 생성해야 하는 경우.
- 상태를 가지는 객체(예: 사용자 입력값을 저장하는 객체)를 사용할 때 유용합니다.
✅ 언제 request, session, application을 사용할까?
- 웹 애플리케이션에서 사용자 요청별, 세션별로 별도 객체를 유지해야 할 때 활용합니다.
- request는 요청 단위로, session은 사용자별로, application은 애플리케이션 전역에서 유지할 경우 유용합니다.
5. 결론
| 스코프 | 사용 상황 |
| singleton | 기본값, 모든 요청에서 동일한 인스턴스 사용 |
| prototype | 요청할 때마다 새로운 인스턴스 생성 |
| request | HTTP 요청마다 새로운 인스턴스 생성 (웹) |
| session | 사용자 세션별 하나의 인스턴스 유지 (웹) |
| application | 애플리케이션 전역에서 하나의 인스턴스 유지 |
🚀 @Scope를 적절히 활용하여 애플리케이션 성능을 최적화해 보세요! 😊