spring
스프링 프레임워크의 핵심 철학은 IoC(Inversion of Control) 컨테이너를 통해 객체(빈, Bean)를 관리하고 의존성을 주입(DI, Dependency Injection)하는 것입니다.
스프링은 애플리케이션 실행 과정에서 필요한 빈들을 생성하고 의존 관계를 설정해줍니다. 그리고 이렇게 등록된 스프링 빈을 사용할 때, 빈이 생성되어 있는지, 혹은 생성 시점이 어떤지 등은 크게 신경 쓰지 않아도 됩니다. 대신, 스프링이 제공하는 스코프(Bean Scope) 설정을 통해 각 빈의 라이프사이클과 생성 횟수를 제어할 수 있습니다.
스프링 빈 스코프(Bean Scope)는 스프링 IoC 컨테이너가 빈의 라이프사이클과 생성·사용 범위를 어떻게 관리할 것인지를 결정하는 정책입니다.
스프링은 아래와 같은 여러 스코프를 제공합니다.
사용자 애플리케이션의 동작 요구사항에 맞춰 스코프를 적절히 설정함으로써, 불필요한 리소스를 아끼고 적절한 시점에 필요한 인스턴스를 생성·관리할 수 있습니다.
@Service
public class SingletonService {
public void doSomething() {
// singleton 스코프의 예시
System.out.println("SingletonService: 항상 동일한 인스턴스가 사용됩니다.");
}
}
Java@Configuration
public class AppConfig {
@Bean
// @Scope("singleton") // 생략 시 singleton이 기본값
public SingletonService singletonService() {
return new SingletonService();
}
}
Java@Component
@Scope("prototype")
public class PrototypeService {
public PrototypeService() {
System.out.println("PrototypeService 객체가 생성되었습니다.");
}
}
Java@RestController
public class PrototypeController {
@Autowired
private ApplicationContext context; // 스프링 컨텍스트를 직접 주입 받음
@GetMapping("/prototype-test")
public String prototypeTest() {
PrototypeService service1 = context.getBean(PrototypeService.class);
PrototypeService service2 = context.getBean(PrototypeService.class);
// 두 객체는 다르다
boolean same = service1 == service2;
return "service1 == service2? " + same;
}
}
Java@Component
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class RequestScopeBean {
private final LocalDateTime createdAt = LocalDateTime.now();
public String getCreationTime() {
return createdAt.toString();
}
}
Java@RestController
public class RequestScopeController {
private final RequestScopeBean requestScopeBean;
// 생성자 주입
public RequestScopeController(RequestScopeBean requestScopeBean) {
this.requestScopeBean = requestScopeBean;
}
@GetMapping("/request-scope")
public String getRequestScopeCreationTime() {
return "RequestScope Bean 생성 시간: " + requestScopeBean.getCreationTime();
}
}
Java@Component
@Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class SessionScopeBean {
private final String sessionId;
public SessionScopeBean() {
// 세션 스코프이므로, 각 사용자 세션마다 인스턴스가 하나씩 생성
this.sessionId = UUID.randomUUID().toString();
}
public String getSessionId() {
return sessionId;
}
}
Java@RestController
public class SessionScopeController {
private final SessionScopeBean sessionScopeBean;
public SessionScopeController(SessionScopeBean sessionScopeBean) {
this.sessionScopeBean = sessionScopeBean;
}
@GetMapping("/session-scope")
public String getSessionScope() {
return "Session ID: " + sessionScopeBean.getSessionId();
}
}
Java@Component
@Scope(value = WebApplicationContext.SCOPE_APPLICATION)
public class ApplicationScopeBean {
private final AtomicInteger counter = new AtomicInteger(0);
public int incrementAndGet() {
return counter.incrementAndGet();
}
}
Java@RestController
public class ApplicationScopeController {
private final ApplicationScopeBean applicationScopeBean;
public ApplicationScopeController(ApplicationScopeBean applicationScopeBean) {
this.applicationScopeBean = applicationScopeBean;
}
@GetMapping("/application-scope")
public String applicationScopeTest() {
int currentCount = applicationScopeBean.incrementAndGet();
return "Application Scope Count: " + currentCount;
}
}
Java@Component
@Scope(value = "websocket", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class WebSocketScopeBean {
private final String id = UUID.randomUUID().toString();
public String getId() {
return id;
}
}
Java@Bean
@Scope("prototype")
public MyBean myBean() {
return new MyBean();
}
Java스프링 빈 스코프는 빈의 생성 시점과 유지·소멸 시점을 결정함으로써, 애플리케이션 동작에 큰 영향을 미칩니다. 알맞은 스코프를 사용하면 메모리 사용 최적화와 동시성 안전성 등을 향상시킬 수 있고, 잘못 사용하면 디버깅이 어려운 상태 관리 문제나 리소스 누수 등 다양한 문제에 직면하게 됩니다.
정리하자면, “어떤 범위의 생명주기를 가진 객체가 필요한가?”라는 질문에 따라 스프링 빈 스코프를 적절히 지정하는 것이 매우 중요합니다. 각 스코프별 특징과 동작 방식을 정확히 이해하고 상황에 맞게 적용하면, 더욱 안정적이고 효율적인 스프링 애플리케이션을 구현할 수 있을 것입니다.
인터넷 네트워크란? "인터넷(Internet)"이라는 단어는 "인터네트워크(Internetwork)"의 줄임말입니다. 즉, 여러 개의 네트워크가 상호 연결되어 전 세계적으로 하나의…
스프링 빈이란? 스프링 프레임워크에서 "스프링 빈(Bean)"이란, IoC(Inversion of Control) 컨테이너가 직접 관리하는 객체를 말합니다. @Component,…
의존성 주입(Dependency Injection)이란? 프로그램을 개발하다 보면, 여러 클래스나 객체들은 서로 필요한 기능을 사용하기 위해 관계를…
컴포넌트 스캔이란? 컴포넌트 스캔(Component Scan)은 스프링 프레임워크가 특정 패키지를 탐색하면서, 스캔 대상에 해당하는 클래스를 찾아…
스프링 빈이란? 스프링 빈(Spring Bean)은 스프링 IoC(Inversion of Control) 컨테이너가 관리하는 자바 객체를 의미합니다. 간단히…
스프링 컨테이너(Spring Container)란? 스프링 컨테이너는 스프링 프레임워크에서 가장 핵심적인 부분으로, IoC(Inversion of Control) 개념을 기반으로…