728x90
Spring에서 @Scope 어노테이션을 사용하면 빈(Bean)의 생성 및 라이프사이클을 관리할 수 있습니다. 스코프를 적절히 설정하면 애플리케이션의 성능과 리소스 활용을 최적화할 수 있습니다.
1. @Scope 어노테이션이란?
@Scope 어노테이션은 Spring 빈의 스코프(생명주기)를 지정하는 데 사용됩니다. 기본적으로 모든 빈은 싱글톤(Singleton) 스코프를 가지지만, 특정 요구사항에 따라 다른 스코프를 적용할 수 있습니다.
1.1 @Scope 기본 사용법
@Component
@Scope("singleton") // 기본값 (생략 가능)
public class SingletonBean {
public SingletonBean() {
System.out.println("SingletonBean 인스턴스 생성됨");
}
}
위 코드에서 @Scope("singleton")은 해당 빈이 애플리케이션 전체에서 하나의 인스턴스만 유지됨을 의미합니다.
2. 싱글톤(Singleton) vs 프로토타입(Prototype) 스코프
2.1 싱글톤 스코프
특징:
- Spring 컨테이너가 단 한 개의 인스턴스만 생성하고 이를 모든 요청에서 공유합니다.
- 애플리케이션이 종료될 때까지 유지됩니다.
- 메모리를 효율적으로 사용할 수 있지만, 상태를 가지면 동시성 문제가 발생할 수 있습니다.
@Component
@Scope("singleton")
public class SingletonBean {
public SingletonBean() {
System.out.println("SingletonBean 인스턴스 생성됨");
}
}
사용 코드
@Autowired
private SingletonBean singletonBean1;
@Autowired
private SingletonBean singletonBean2;
public void checkSingleton() {
System.out.println(singletonBean1 == singletonBean2); // true
}
2.2 프로토타입 스코프
특징:
- 매번 빈을 요청할 때마다 새로운 인스턴스가 생성됩니다.
- Spring 컨테이너가 라이프사이클을 관리하지 않으며, 수동으로 소멸 처리가 필요합니다.
- 메모리 사용량이 증가할 가능성이 있습니다.
@Component
@Scope("prototype")
public class PrototypeBean {
public PrototypeBean() {
System.out.println("PrototypeBean 인스턴스 생성됨");
}
}
사용 코드
@Autowired
private PrototypeBean prototypeBean1;
@Autowired
private PrototypeBean prototypeBean2;
public void checkPrototype() {
System.out.println(prototypeBean1 == prototypeBean2); // false
}
3. 싱글톤과 프로토타입 관계에서 발생하는 문제
3.1 싱글톤 빈이 프로토타입 빈을 포함할 때
싱글톤 빈이 프로토타입 빈을 의존성 주입받으면 프로토타입 빈이 싱글톤 빈이 생성될 때 한 번만 주입되고, 이후에는 같은 인스턴스를 계속 사용하는 문제가 발생합니다.
❌ 잘못된 예제 (항상 같은 프로토타입 빈 사용됨)
@Component
@Scope("singleton")
public class SingletonService {
private final PrototypeBean prototypeBean;
@Autowired
public SingletonService(PrototypeBean prototypeBean) {
this.prototypeBean = prototypeBean;
}
public void usePrototypeBean() {
System.out.println("PrototypeBean 사용됨: " + prototypeBean);
}
}
해결 방법
3.2 해결 방법 1: ObjectProvider 사용
Spring의 ObjectProvider를 사용하면 매번 새로운 프로토타입 빈을 가져올 수 있습니다.
@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 사용됨: " + prototypeBean);
}
}
3.3 해결 방법 2: @Lookup 사용
@Lookup을 사용하면 새로운 프로토타입 빈을 동적으로 주입받을 수 있습니다.
@Component
public abstract class SingletonService {
public void usePrototypeBean() {
PrototypeBean prototypeBean = getPrototypeBean();
System.out.println("PrototypeBean 사용됨: " + prototypeBean);
}
@Lookup
protected abstract PrototypeBean getPrototypeBean();
}
4. 스코프별 리소스 관리 비교
스코프 유형 객체 생성 시점 라이프사이클 관리 리소스 관리 특징
| singleton | 애플리케이션 시작 시 1회 | Spring 컨테이너가 직접 관리 | 메모리 효율적, 공유 가능, GC 부담 적음 |
| prototype | 빈이 요청될 때마다 | 개발자가 직접 관리 | 매번 새로운 객체 생성, GC 대상 |
5. 결론
- 싱글톤 빈은 애플리케이션 전반에서 공유할 리소스에 적합 (예: 서비스 계층, 캐시)
- 프로토타입 빈은 매번 새로운 객체를 생성해야 하는 경우 적합 (예: 트랜잭션 처리, 사용자 요청 기반 객체 생성)
- 싱글톤 내에서 프로토타입 빈을 적절히 사용하려면 ObjectProvider 또는 @Lookup을 활용
적절한 스코프 선택을 통해 성능을 최적화하고, 메모리 효율성을 고려한 애플리케이션을 설계하세요! 🚀
728x90
'개발 > Spring' 카테고리의 다른 글
| Spring Data 개요 (0) | 2025.02.12 |
|---|---|
| Spring @PostConstruct와 @PreDestroy 어노테이션 (1) | 2025.02.11 |
| Spring @Lazy 어노테이션: 빈 로딩 최적화를 위한 핵심 기능 (0) | 2025.02.11 |
| Spring @Primary와 @Qualifier 어노테이션 쉽게 이해하기 (0) | 2025.02.11 |
| Spring에서 @Data 어노테이션 (0) | 2025.02.05 |