IT기술/MSA (with. springboot)

Spring Bean Scope 완벽 가이드: MSA 환경에서의 객체 생명주기 관리

후스파 2025. 7. 4. 23:34
반응형

마이크로서비스 아키텍처(MSA)에서 스프링 빈의 스코프는 객체의 생명주기를 관리하는 중요한 요소입니다. 스프링에서는 다양한 스코프를 제공하여 애플리케이션의 요구사항에 맞게 빈의 생성과 소멸을 조절할 수 있습니다.
이번 포스트에서는 스프링 빈 스코프의 종류와 각 스코프의 특징에 대해 자세히 살펴보겠습니다.


스프링 빈 스코프 개요

스프링 빈 스코프는 빈 객체의 생명주기를 정의하는 것으로, 빈의 생성부터 소멸까지의 과정을 포함합니다. 기본적으로 스프링 빈의 스코프는 singleton으로 설정되어 있으며, @Scope 어노테이션을 통해 다른 스코프를 지정할 수 있습니다.
빈 스코프는 빈이 존재할 수 있는 범위를 의미하며, 스프링 컨테이너에서 관리하는 자바 객체인 빈의 생성과 소멸을 클라이언트에서 관리해야 하는 경우도 있습니다.


스프링 빈 스코프 종류

스프링에서는 6가지 스코프를 제공하며, 각 스코프는 다음과 같은 특성을 가지고 있습니다.

singleton

  • 설명: 기본값으로, 해당 빈은 스프링 컨테이너에 오직 하나만 존재합니다
  • 특징: 애플리케이션 전체에서 동일한 인스턴스를 공유하므로 메모리 사용이 효율적입니다. 그러나 멀티스레드 환경에서는 주의가 필요합니다
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component
@Scope("singleton")
public class SingletonBean {
    // 상태를 가지지 않는 stateless 설계 필요
    public String processData(String input) {
        return "Processed: " + input;
    }
}

prototype

  • 설명: 컨테이너에 여러 개의 빈 인스턴스를 생성할 수 있습니다
  • 특징: 의존성 주입 시마다 새로운 객체를 생성하여 주입하므로 상태를 유지해야 하는 경우에 유용합니다
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component
@Scope("prototype")
public class PrototypeBean {
    private int counter = 0;

    public void increment() {
        counter++;
    }

    public int getCounter() {
        return counter;
    }
}

request

  • 설명: 웹 기능에 한정된 스코프입니다
  • 특징: HTTP 요청을 처리할 때마다 새로운 객체를 생성합니다. 각 요청마다 고유한 인스턴스를 제공하여 상태를 격리합니다
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component
@Scope("request")
public class RequestBean {
    private String requestId;

    public void setRequestId(String requestId) {
        this.requestId = requestId;
    }

    public String getRequestId() {
        return requestId;
    }
}

session

  • 설명: 웹 기능에 한정된 스코프입니다
  • 특징: HTTP 세션과 대응하여 새로운 객체를 생성합니다. 각 세션마다 고유한 인스턴스를 제공하여 사용자 상태를 유지합니다
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component
@Scope("session")
public class SessionBean {
    private String userId;
    private List userActions = new ArrayList<>();

    public void addUserAction(String action) {
        userActions.add(action);
    }
}

application

  • 설명: 웹 기능에 한정된 스코프입니다
  • 특징: Servlet 컨텍스트와 대응하여 새로운 객체를 생성합니다. 애플리케이션 전체에서 하나의 인스턴스를 공유합니다
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component
@Scope("application")
public class ApplicationBean {
    private final Map applicationCache = new ConcurrentHashMap<>();

    public void putCache(String key, Object value) {
        applicationCache.put(key, value);
    }
}

websocket

  • 설명: 웹 기능에 한정된 스코프입니다
  • 특징: WebSocket 세션과 대응하여 새로운 객체를 생성합니다. 실시간 통신을 필요로 하는 경우에 유용합니다
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component
@Scope("websocket")
public class WebSocketBean {
    private String sessionId;
    private Queue messageQueue = new LinkedList<>();

    public void addMessage(String message) {
        messageQueue.offer(message);
    }
}

멀티스레드 안전성

스프링 애플리케이션을 작성할 때는 항상 멀티스레드 환경에서의 안전성을 확인하는 것이 중요합니다.

Singleton Bean의 Thread Safety

@Component
public class ThreadSafeService {
    // 위험: 상태를 가진 필드
    private int counter = 0;

    // 안전: 상태를 가지지 않는 필드
    private final String LOG_PATH = "/logs/";

    // 안전: 메서드 파라미터 사용
    public int calculate(int a, int b) {
        return a + b;
    }
}

Prototype Bean 활용 예시

@Component
@Scope("prototype")
public class StatefulService {
    private int state = 0;

    public void setState(int state) {
        this.state = state;
    }

    public int getState() {
        return state;
    }
}

실무 활용 패턴

ObjectProvider를 활용한 Prototype Bean 사용

@Service
public class OrderService {
    private final ObjectProvider orderProcessorProvider;

    public OrderService(ObjectProvider orderProcessorProvider) {
        this.orderProcessorProvider = orderProcessorProvider;
    }

    public void processOrder(Order order) {
        OrderProcessor processor = orderProcessorProvider.getObject();
        processor.process(order);
    }
}

웹 스코프 Proxy 모드 활용

@Component
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class RequestScopedBean {
    private String requestData;

    public void setRequestData(String data) {
        this.requestData = data;
    }

    public String getRequestData() {
        return requestData;
    }
}

결론

스프링 빈 스코프는 MSA에서 객체의 생명주기를 효과적으로 관리하는 데 중요한 역할을 합니다. 각 스코프의 특성을 이해하고 적절하게 활용하면, 애플리케이션의 성능과 유지보수성을 크게 향상시킬 수 있습니다.
핵심 가이드라인:

  • 기본적으로 Singleton 사용, 상태가 없는 stateless 설계
  • 상태 관리가 필요한 경우 Prototype 스코프 고려
  • 웹 애플리케이션에서는 request, session 스코프 적절히 활용
  • 멀티스레드 환경에서의 Thread Safety 항상 고려

스프링의 다양한 스코프를 통해 필요에 맞는 빈 관리를 효율적으로 구현해 보시기 바랍니다.

반응형