✅ 스프링 빈 스코프 정리
💡 빈 스코프란?
스프링 컨테이너에서 빈이 생성되고 존재하며 소멸되는 범위(Lifecycle) 를 의미합니다.
- 기본 스코프는
singleton - 빈의 생명주기, 공유 범위, 관리 방식 조절 가능
🔹 주요 빈 스코프 종류
1. 📌 Singleton (기본값)
- 컨테이너 시작 ~ 종료까지 하나의 인스턴스 유지
- 모든 요청에 같은 인스턴스 반환
stateless하게 설계 권장
@Component
@Scope("singleton") // 생략 가능
public class MySingletonBean {
}
2. 📌 Prototype
- 요청할 때마다 새로운 인스턴스 생성
- 초기화까지만 스프링이 관리, 소멸은 관리 안함
@PreDestroy호출 ❌
@Component
@Scope("prototype")
public class MyPrototypeBean {
@PostConstruct
public void init() {
System.out.println("초기화");
}
@PreDestroy
public void destroy() {
System.out.println("소멸"); // 호출되지 않음
}
}
3. 📌 웹 스코프 (웹 환경에서만 사용 가능)
| 스코프 이름 | 유지 범위 |
|---|---|
request |
HTTP 요청 1건 처리 동안 |
session |
HTTP 세션 유지되는 동안 |
application |
서블릿 컨텍스트와 생명주기 동일 |
websocket |
WebSocket 연결 유지되는 동안 |
@Component
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class MyRequestBean {
}
💡 프록시를 사용하면 싱글톤 빈에서도 안전하게 request 스코프 빈을 사용할 수 있음
🔸 빈 스코프 지정 방법
| 방식 | 예시 코드 |
|---|---|
| 컴포넌트 스캔 | @Scope("prototype") |
| 수동 등록 (설정) | @Bean 메서드에 @Scope("...") 지정 |
@Configuration
public class AppConfig {
@Bean
@Scope("prototype")
public MyPrototypeBean prototypeBean() {
return new MyPrototypeBean();
}
}
⚠️ 싱글톤 빈에서 프로토타입 빈을 사용할 때 주의점
- 프로토타입 빈을 필드 주입하면 한 번만 생성되어 재사용됨
- 프로토타입의 의도(매번 새로운 인스턴스)와 맞지 않음
❌ 잘못된 예
@Component
public class SingletonClient {
private final MyPrototypeBean prototype;
public SingletonClient(MyPrototypeBean prototype) {
this.prototype = prototype;
}
public void logic() {
prototype.doSomething(); // 항상 같은 인스턴스
}
}
✅ 해결 방법
1. ObjectProvider 사용 (Spring 전용)
@Component
public class SingletonClient {
@Autowired
private ObjectProvider<MyPrototypeBean> provider;
public void logic() {
MyPrototypeBean prototype = provider.getObject(); // 매번 새로운 인스턴스
prototype.doSomething();
}
}
2. javax.inject.Provider 사용 (자바 표준, 외부 의존성 필요)
@Component
public class SingletonClient {
@Inject
private Provider<MyPrototypeBean> provider;
public void logic() {
MyPrototypeBean prototype = provider.get();
}
}
⚠️ 웹 스코프 빈을 싱글톤 빈에서 사용할 때 주의점
request,session스코프 빈을 직접 주입하면 오류 발생- 이유: 싱글톤 빈은 애플리케이션 시작 시 생성되지만, 웹 스코프 빈은 요청이 들어올 때 생성되기 때문
- 즉, 아직 존재하지 않는 빈을 주입하려 하므로 예외 발생
✅ 프록시 방식으로 해결
@Component
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class MyRequestBean {
}
@Component
public class MyService {
@Autowired
private MyRequestBean requestBean; // 프록시 객체 주입
}
🔍 프록시(Proxy)란?
스프링이 진짜 웹 스코프 빈 대신에 가짜 프록시 객체를 먼저 주입해줌
이 프록시 객체는 실제 요청이 올 때까지 기다렸다가, 그 시점에 진짜 빈을 찾아서 동작을 위임함
requestBean.doSomething()호출 시
👉 프록시가 현재 요청 스코프에 해당하는 실제MyRequestBean을 찾아서 대신 실행
📌 프록시의 장점
- 싱글톤 빈 안에서도 안전하게 웹 스코프 빈 사용 가능
- 클라이언트 코드는 마치 일반 빈처럼 사용할 수 있음 (프록시인지 신경 쓸 필요 없음)
- 스코프의 생명주기를 신경쓰지 않아도 됨
⚠️ 주의할 점
- 프록시는 실제 객체가 아니므로,
==비교나instanceof검사 시 주의 @Scope(..., proxyMode = ScopedProxyMode.TARGET_CLASS)는 CGLIB 기반 프록시 (클래스 기반)- 인터페이스 기반 프록시가 필요하면
ScopedProxyMode.INTERFACES사용
- 인터페이스 기반 프록시가 필요하면
✅ 프록시 요약 정리
| 항목 | 설명 |
|---|---|
| 프록시 역할 | 실제 스코프 빈을 대신해 먼저 주입되는 가짜 객체 |
| 생성 시점 | 애플리케이션 초기 (싱글톤 빈 생성 시점) |
| 실제 객체 호출 시점 | 실제 요청(request 등)이 발생한 후 |
| 설정 방법 | @Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS) |
🧾 마무리 요약
- 싱글톤: 애플리케이션 전역, 상태 없이 사용
- 프로토타입: 매번 새 인스턴스 필요할 때
- 웹 스코프: 요청/세션/앱별 빈 관리
- Provider, 프록시 사용으로 스코프 조합 문제 해결
'Framework > Spring' 카테고리의 다른 글
| [Spring] 스프링 자동 빈 등록 vs 수동 빈 등록 (0) | 2025.04.05 |
|---|---|
| [Spring] 의존관계 주입 (Dependency Injection) (0) | 2025.04.02 |
| [Spring] 싱글톤 패턴과 스프링 컨테이너 (0) | 2025.04.02 |