Spring

8. @Scope를 사용하여 싱글톤, 프로토타입 정하기

leek94 2024. 9. 12. 15:34

기본적으로 Spring 컨테이너는 인스턴스를 싱글톤으로 저장하고 있다.

하지만 @Scope를 사용해서 프로토 타입으로 인스턴스를 저장하면  호출시 다른 인스턴스가 호출된다.

@Component
class NormalClass {
	
}


@Scope(value=ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Component
class PrototypeClass {
	
}


@Configuration
@ComponentScan
public class BeanScopesLauncherApplication {
	
	public static void main(String[] args) {

		try (var context = 
				new AnnotationConfigApplicationContext
					(BeanScopesLauncherApplication.class)) {
			
			System.out.println(context.getBean(NormalClass.class));
			System.out.println(context.getBean(NormalClass.class));
			System.out.println(context.getBean(NormalClass.class));
			System.out.println(context.getBean(NormalClass.class));
			System.out.println(context.getBean(NormalClass.class));
			System.out.println(context.getBean(NormalClass.class));
			
			System.out.println(context.getBean(PrototypeClass.class));
			System.out.println(context.getBean(PrototypeClass.class));
			System.out.println(context.getBean(PrototypeClass.class));
			System.out.println(context.getBean(PrototypeClass.class));
			

		}
	}
}

결과

com.in28minutes.learnspringframework.examples.d1.NormalClass@478db956

com.in28minutes.learnspringframework.examples.d1.NormalClass@478db956

com.in28minutes.learnspringframework.examples.d1.NormalClass@478db956

com.in28minutes.learnspringframework.examples.d1.NormalClass@478db956

com.in28minutes.learnspringframework.examples.d1.NormalClass@478db956

com.in28minutes.learnspringframework.examples.d1.NormalClass@478db956

com.in28minutes.learnspringframework.examples.d1.PrototypeClass@6ca18a14

com.in28minutes.learnspringframework.examples.d1.PrototypeClass@c667f46

com.in28minutes.learnspringframework.examples.d1.PrototypeClass@51bd8b5c

com.in28minutes.learnspringframework.examples.d1.PrototypeClass@7b50df34

 

위의 노말클래스는 싱글톤으로 매번 같은 인스턴스가 호출되지만

프로토클래스는 다른 인스턴스가 호출된다

 

 

구분 싱글톤(Singleton) 프로토타입(Prototype)
설명 스프링 컨테이너에서 빈을 한 번만 생성하여 공유 요청할 때마다 새로운 인스턴스를 생성
빈 생성 횟수 한 번만 생성 (애플리케이션 전체에서 하나의 인스턴스) 요청할 때마다 새로운 빈이 생성됨
라이프사이클 스프링 컨테이너가 시작될 때 생성되고, 종료될 때 소멸 빈이 호출될 때마다 생성되고, 컨테이너가 관리하지 않음
상황에 적합 상태를 공유하는 객체나 재사용이 필요한 객체에 적합 상태를 공유하지 않는 객체나 매번 새로운 인스턴스가 필요한 경우
장점 메모리 절약, 성능 최적화, 빈 관리 용이 상태 유지 없이 독립적인 작업을 처리하는 데 유리
단점 상태가 공유되므로, 여러 스레드에서 동시 접근 시 주의 필요 매번 새로운 객체가 생성되므로 메모리 및 성능에 부하 가능
예시 사용 @Scope("singleton") (기본 스코프) @Scope("prototype")
의존성 주입 시 동작 주입 시점에 하나의 인스턴스가 생성되고 재사용됨 주입할 때마다 새로운 인스턴스를 주입
스프링 관리 여부 스프링이 라이프사이클을 관리 (생성과 소멸) 생성 후 스프링이 관리하지 않음 (사용자가 수동으로 관리해야 함)
사용 예시 서비스, 리포지토리 등 상태가 공유되어도 괜찮은 객체 사용자 세션, 요청별로 상태가 달라지는 객체

 

 

-> 거의 대부분은 싱글톤 방식을 사용

 

그렇다면 언제 프로토 타입을 사용해야 할까?

-> 여러 유저의 정보를 저장하거나 StateFul한 처리를 해야할 때 사용할 수 있다.

-> 각 요청마다 독립적인 상태를 유지해야할 때 프로토 타입 스코프를 사용한다.

 

  • 프로토타입 스코프는 빈을 요청할 때마다 새로운 객체를 생성합니다.
    즉, 프로토타입 빈을 사용하면 각 요청마다 독립적인 객체 인스턴스가 생성되므로, 유저별로 서로 다른 상태를 저장하고 관리할 수 있습니다.
  • 예를 들어, 유저가 로그인하고 나서 세션 동안 특정 정보를 저장하거나 요청마다 다른 유저 정보가 관리되어야 한다면:
    • 프로토타입 빈을 사용하여 유저마다 개별 상태를 가진 객체가 생성됩니다.
    • 이 경우 한 유저의 정보가 다른 유저와 섞이는 문제가 발생하지 않습니다.