카테고리 없음

Spring @Scope 어노테이션: 빈의 생명주기 관리하기

피터JK 2025. 2. 11. 16:12
728x90

Spring Framework에서 @Scope 어노테이션은 스프링 빈(Bean)의 범위(Scope) 를 지정하는 데 사용됩니다. 기본적으로 빈은 싱글톤(Singleton)으로 생성되지만, @Scope를 사용하면 요청할 때마다 새로운 인스턴스를 생성하거나 특정 컨텍스트 내에서 유지되도록 조정할 수 있습니다.


1. @Scope 기본 개념

@Scope는 빈이 생성되고 관리되는 방식을 정의하는 어노테이션으로, 빈의 생명주기를 결정합니다. Spring에서는 여러 가지 범위를 지원하며, 가장 많이 사용되는 범위는 다음과 같습니다:

스코프 유형 설명

singleton (기본값) 애플리케이션 전체에서 단 하나의 인스턴스만 생성
prototype 요청할 때마다 새로운 인스턴스를 생성
request HTTP 요청이 있을 때마다 새로운 인스턴스를 생성 (웹 환경)
session 사용자 세션별로 하나의 인스턴스 유지 (웹 환경)
application 애플리케이션 컨텍스트 범위에서 하나의 인스턴스 유지 (웹 환경)
websocket 웹소켓 세션별로 하나의 인스턴스 유지 (웹 환경)

2. @Scope 사용 방법

(1) 싱글톤(Singleton) 스코프 (기본값)

Spring 빈의 기본 스코프는 singleton으로, 한 번만 생성되고 애플리케이션이 종료될 때까지 유지됩니다.

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component
@Scope("singleton")  // 기본값, 생략 가능
public class SingletonBean {
    public SingletonBean() {
        System.out.println("SingletonBean 인스턴스 생성");
    }
}

📌 동일한 빈을 여러 번 주입해도 항상 같은 인스턴스를 반환합니다.

(2) 프로토타입(Prototype) 스코프

prototype 스코프를 사용하면, 빈이 주입될 때마다 새로운 인스턴스가 생성됩니다.

@Component
@Scope("prototype")
public class PrototypeBean {
    public PrototypeBean() {
        System.out.println("PrototypeBean 인스턴스 생성");
    }
}

📌 매번 새로운 객체가 생성되므로, 상태를 가지는 객체를 사용할 때 유용합니다.

✅ 싱글톤 빈에서 프로토타입 빈을 주입할 때 주의점

  • 싱글톤 빈이 프로토타입 빈을 주입받으면, 프로토타입 빈은 최초 1회만 생성되며 동일한 객체가 재사용됩니다.
  • 이를 해결하려면 ObjectFactory 또는 Provider를 사용할 수 있습니다.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Lookup;
import org.springframework.stereotype.Component;

@Component
public class SingletonService {
    @Autowired
    private PrototypeBean prototypeBean;  // 항상 같은 인스턴스 사용됨
}

해결 방법: ObjectProvider 사용하기

import org.springframework.beans.factory.ObjectProvider;
import org.springframework.stereotype.Component;

@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 사용");
    }
}

3. 웹 환경에서의 스코프

(1) Request 스코프 (HTTP 요청별 새로운 인스턴스)

웹 애플리케이션에서 @Scope("request")를 사용하면 HTTP 요청이 발생할 때마다 새로운 인스턴스를 생성합니다.

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component
@Scope("request")
public class RequestBean {
    public RequestBean() {
        System.out.println("RequestBean 인스턴스 생성");
    }
}

📌 사용자가 새로운 요청을 보낼 때마다 새로운 객체가 생성됩니다.

(2) Session 스코프 (사용자 세션별 인스턴스 유지)

사용자 세션이 유지되는 동안 하나의 인스턴스를 공유합니다.

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component
@Scope("session")
public class SessionBean {
    public SessionBean() {
        System.out.println("SessionBean 인스턴스 생성");
    }
}

📌 동일한 사용자가 요청하는 동안 같은 인스턴스를 재사용합니다.

(3) Application 스코프 (애플리케이션 내에서 하나의 인스턴스 유지)

애플리케이션 전체에서 하나의 인스턴스를 공유합니다.

@Component
@Scope("application")
public class ApplicationBean {
    public ApplicationBean() {
        System.out.println("ApplicationBean 인스턴스 생성");
    }
}

📌 서버가 종료될 때까지 하나의 객체만 유지됩니다.


4. @Scope를 사용할 때의 고려 사항

✅ 언제 singleton을 사용할까?

  • 대부분의 서비스(Service) 계층 빈은 싱글톤으로 유지하는 것이 적절합니다.
  • 상태를 가지지 않는 빈이거나, 여러 요청 간 공유되어도 문제가 없는 경우 사용합니다.

✅ 언제 prototype을 사용할까?

  • 각 요청마다 새로운 인스턴스를 생성해야 하는 경우.
  • 상태를 가지는 객체(예: 사용자 입력값을 저장하는 객체)를 사용할 때 유용합니다.

✅ 언제 request, session, application을 사용할까?

  • 웹 애플리케이션에서 사용자 요청별, 세션별로 별도 객체를 유지해야 할 때 활용합니다.
  • request는 요청 단위로, session은 사용자별로, application은 애플리케이션 전역에서 유지할 경우 유용합니다.

5. 결론

스코프 사용 상황
singleton 기본값, 모든 요청에서 동일한 인스턴스 사용
prototype 요청할 때마다 새로운 인스턴스 생성
request HTTP 요청마다 새로운 인스턴스 생성 (웹)
session 사용자 세션별 하나의 인스턴스 유지 (웹)
application 애플리케이션 전역에서 하나의 인스턴스 유지

🚀 @Scope를 적절히 활용하여 애플리케이션 성능을 최적화해 보세요! 😊

728x90