25.02.26 TIL 스코프

신성훈·2025년 2월 26일
0

TIL

목록 보기
139/162

1. Spring Bean의 스코프란?

Spring에서 Bean의 스코프Bean의 생성 및 관리되는 범위를 의미합니다.
기본적으로 Spring의 Bean은 Singleton으로 관리되지만 다른 스코프를 설정할 수도 있습니다.

  • Spring에서 지원하는 주요 스코프
스코프설명
Singleton(기본값) 하나의 객체만 생성하여 공유
Prototype요청할 때마다 새로운 객체 생성
RequestHTTP 요청마다 새로운 객체 생성 (웹)
SessionHTTP 세션마다 새로운 객체 생성 (웹)
Application애플리케이션 내에서 하나의 객체만 생성

이번 글에서는 Prototype 스코프에 대해 집중적으로 살펴보겠습니다.


2. Prototype 스코프란?

Prototype 스코프요청할 때마다 새로운 객체를 생성하는 Bean 스코프입니다.

@Component
@Scope("prototype") // 프로토타입 스코프 설정
public class PrototypeBean {
    public PrototypeBean() {
        System.out.println("Prototype Bean 생성됨!");
    }
}

이렇게 설정하면 PrototypeBean을 요청할 때마다 새로운 객체가 생성됩니다.


3. Singleton vs Prototype 차이

① 싱글톤 (Singleton)

@Component
@Scope("singleton") // (기본값)
public class SingletonBean {
}
  • 한 번만 생성되어 모든 곳에서 같은 인스턴스를 공유
  • Spring이 Bean을 컨테이너 초기화 시점에 생성
  • 메모리 절약, 성능 향상 가능하지만, 상태 유지 시 문제 발생 가능

② 프로토타입 (Prototype)

@Component
@Scope("prototype")
public class PrototypeBean {
}
  • 요청할 때마다 새로운 객체가 생성됨
  • Spring이 Bean을 컨테이너 초기화 시점이 아닌, 요청 시 생성
  • 상태를 가지는 Bean 관리에 유리하지만, 직접 관리해야 할 수도 있음

4. Prototype Bean 사용 예제

1) 기본적인 생성 확인

public class PrototypeScopeTest {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context =
            new AnnotationConfigApplicationContext(AppConfig.class);

        PrototypeBean bean1 = context.getBean(PrototypeBean.class);
        PrototypeBean bean2 = context.getBean(PrototypeBean.class);

        System.out.println(bean1 == bean2); // false (다른 객체)
    }
}

-> bean1 != bean2
즉, 요청할 때마다 새로운 객체가 생성됨을 확인할 수 있습니다.


5. 주의할 점: Singleton Bean과 함께 사용할 경우

Prototype Bean은 Spring이 관리하지 않기 때문에 자동으로 소멸되지 않습니다.
이 때문에 싱글톤 Bean에서 프로토타입 Bean을 사용할 때 주의가 필요합니다.

문제 발생 예시

@Component
@Scope("singleton")
public class SingletonBean {
    @Autowired
    private PrototypeBean prototypeBean; // 주입 시점에 객체가 고정됨

    public void print() {
        System.out.println(prototypeBean);
    }
}

위 코드를 실행하면 항상 같은 Prototype 객체가 반환됩니다.
왜냐하면 Spring이 SingletonBean을 생성할 때 prototypeBean을 한 번만 주입하기 때문입니다.

해결 방법 1: ObjectProvider 사용

@Component
@Scope("singleton")
public class SingletonBean {
    @Autowired
    private ObjectProvider<PrototypeBean> prototypeBeanProvider;

    public void print() {
        PrototypeBean prototypeBean = prototypeBeanProvider.getObject();
        System.out.println(prototypeBean);
    }
}

-> getObject()를 호출할 때마다 새로운 객체가 생성됨

해결 방법 2: @Lookup 애노테이션 사용

@Component
@Scope("singleton")
public class SingletonBean {
    @Lookup
    public PrototypeBean getPrototypeBean() {
        return null; // Spring이 자동으로 오버라이드 함
    }

    public void print() {
        System.out.println(getPrototypeBean());
    }
}

-> @Lookup을 사용하면 자동으로 새로운 Prototype Bean을 주입받을 수 있음


6. Prototype Bean의 장점과 단점

장점

  • 상태를 가지는 Bean을 사용할 때 유용
  • 싱글톤 Bean과 분리하여 독립적인 객체 관리 가능
  • 요청할 때만 Bean을 생성하므로 초기 메모리 사용량 절약

단점

  • 객체가 계속 생성되므로 메모리 사용량 증가 가능
  • Spring이 생명주기를 관리하지 않으므로 수동으로 소멸 처리 필요
  • 싱글톤 Bean에서 사용할 경우 추가적인 설정 필요

7. 마무리

Spring의 기본 스코프가 Singleton인 이유는 성능과 효율성 때문이지만 Prototype 스코프는 상태를 가지는 객체를 독립적으로 관리할 때 매우 유용하다는 것을 배웠습니다.
싱글톤 Bean과 함께 사용할 때 관리해야 하는 점이 많다는 것이 중요하다고 느꼈습니다.

profile
조급해하지 말고, 흐름을 만들고, 기록하면서 쌓아가자.

0개의 댓글