-
Spring Framework 시리즈 5화 – 스프링 빈 스코프 정리기술과 산업/언어 및 프레임워크 2025. 5. 26. 10:52728x90
Spring Framework의 다양한 빈 스코프(Scope)인 Singleton, Prototype, Request, Session, Application의 동작 방식과 차이점을 예제와 함께 설명합니다. 웹 애플리케이션에서 올바른 스코프 선택이 왜 중요한지도 함께 살펴봅니다.
빈 스코프란 무엇인가?
Spring에서 Bean은 기본적으로 ApplicationContext에 의해 관리되며, 생성 방식과 범위를 결정하는 속성이 바로 **스코프(scope)**입니다.
스코프는 "이 빈이 어떤 범위로 존재해야 하는가?"를 정의합니다.
스프링에서 제공하는 스코프 종류
스코프 명칭 적용 대상 설명
singleton (기본값) 전체 애플리케이션 컨테이너 당 1개의 인스턴스 prototype 요청 시마다 호출할 때마다 새로운 인스턴스 생성 request 웹 요청 단위 HTTP 요청마다 별도 인스턴스 (서버 사이드에서만) session 웹 세션 단위 세션별 1개의 인스턴스 application 서블릿 컨텍스트 단위 서블릿 컨텍스트 범위에서 공유 websocket 웹소켓 세션 단위 웹소켓 커넥션별 인스턴스 (Spring 4+)
1. 기본 스코프 – Singleton
@Component @Scope("singleton") public class SingletonBean { public SingletonBean() { System.out.println("SingletonBean 생성됨"); } }
- 동일한 Bean을 계속 재사용
- 메모리 절약
- 상태를 가지면 위험 → 멀티스레드 환경에서 데이터 충돌 발생 가능
2. Prototype – 매번 새로운 객체 생성
@Component @Scope("prototype") public class PrototypeBean { public PrototypeBean() { System.out.println("PrototypeBean 생성됨"); } }
PrototypeBean bean1 = context.getBean(PrototypeBean.class); PrototypeBean bean2 = context.getBean(PrototypeBean.class);
- 호출할 때마다 매번 새로운 객체
- 초기화 메서드만 호출됨, 소멸 메서드는 Spring이 관리하지 않음
- 객체 수명 관리를 개발자가 직접 해야 함
3. Request – HTTP 요청마다 별도 인스턴스
@Component @Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS) public class RequestScopedBean { public RequestScopedBean() { System.out.println("RequestScopedBean 생성됨"); } }
- Spring MVC 웹 컨트롤러에서 유용
- 각 HTTP 요청마다 새로운 빈 생성
- proxyMode 설정 필수 (CGLIB 프록시 생성)
예제:
@RestController public class SampleController { private final RequestScopedBean bean; public SampleController(RequestScopedBean bean) { this.bean = bean; } @GetMapping("/hello") public String hello() { return "Bean: " + bean.toString(); } }
4. Session – 세션별로 빈 유지
@Component @Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS) public class SessionScopedBean { public SessionScopedBean() { System.out.println("SessionScopedBean 생성됨"); } }
- 사용자의 세션이 유지되는 동안 동일한 Bean 사용
- 로그인 사용자 정보를 저장할 때 활용
- 세션 무효화 시 함께 제거
5. Application – 서블릿 컨텍스트 단위 공유
@Component @Scope(value = WebApplicationContext.SCOPE_APPLICATION) public class ApplicationScopedBean { public ApplicationScopedBean() { System.out.println("ApplicationScopedBean 생성됨"); } }
- 전체 웹 애플리케이션 컨텍스트에서 공유
- 웹 애플리케이션이 살아있는 동안 유지
- 보통 캐시성 데이터에 사용
웹 스코프는 왜 proxyMode가 필요한가?
Spring MVC 컨트롤러에서 request, session 스코프를 사용하려면 @Autowired 시점에서는 아직 해당 범위가 활성화되지 않았기 때문에 프록시 객체로 대체해야 합니다.
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
이렇게 하면 Spring은 실제 요청 시점에 프록시가 실제 Bean을 가져와 대체합니다.
프록시 없이 사용하면 IllegalStateException: No thread-bound request 오류가 발생합니다.
마무리 – 상태에 따라 스코프를 구분하라
스프링의 기본 동작은 싱글톤이지만, 요청, 세션, 다중 사용자 처리가 필요한 경우에는 반드시 적절한 스코프를 선택해야 합니다.
잘못된 스코프 선택은 데이터 오염, 사용자 정보 충돌, 보안 취약성을 초래할 수 있습니다.상황 권장 스코프
대부분의 서비스 컴포넌트 singleton 상태가 있는 객체, 계산기 등 prototype 요청마다 값이 다른 로그인 정보 request 사용자 세션 정보 (장바구니 등) session 전역 캐시성 정보 application 다음 6화에서는 실무에서 가장 흔히 마주하는 의존성 순환 문제와 그 해결 전략에 대해 다룹니다.
서로를 주입하려는 두 객체 사이의 순환 참조가 어떻게 발생하는지, 이를 회피하기 위한 구조 설계 방법과 @Lazy, 세터 주입 방식 등을 실습할 예정입니다.728x90'기술과 산업 > 언어 및 프레임워크' 카테고리의 다른 글
NestJS 마스터 시리즈 15화. 인증 시스템 구현 (1) – JWT 기반 로그인 시스템 만들기 (1) 2025.05.27 전자정부 표준프레임워크 시리즈 10화 – 파일 업로드와 다운로드 처리 구조 분석: EgovFileMngService의 내부 작동 방식 (1) 2025.05.26 Spring Boot 시리즈 36편 – Elasticsearch 연동: 검색 기능 확장을 위한 인덱싱, 매핑, 쿼리 전략 (0) 2025.05.26 FastAPI 시리즈 11화 - OAuth2 이해와 FastAPI 로그인 인증 시스템 구축 (0) 2025.05.23 Spring Boot 시리즈 35편 – Spring Cloud Config: 설정 중앙화 전략과 운영환경 속 안전한 구성관리 (0) 2025.05.23