티스토리 뷰

반응형

서론

Spring에서 bean 객체는 기본적으로 Singleton pattern으로 생성됩니다.

싱글톤 패턴으로 bean 객체를 생성하는 것에서 얻을 수 있는 이점은 아래와 같습니다.

 

1. 메모리 효율성

  • 리소스 절약: 싱글톤 스코프는 애플리케이션 내에서 단 하나의 인스턴스만 생성합니다. 이는 동일한 객체를 여러 번 생성할 필요가 없어 메모리 사용량을 줄이고, 리소스를 효율적으로 사용할 수 있게 합니다.

2. 공유 상태 관리

  • 중앙 집중식 상태 관리: 싱글톤 빈은 애플리케이션 전반에 걸쳐 공유되는 상태나 설정 정보를 관리하는 데 유용합니다. 예를 들어, 데이터베이스 연결 풀, 설정 관리자, 캐시 등은 여러 컴포넌트에서 공유되어 사용되므로 싱글톤으로 관리하는 것이 적합합니다.

3. 성능 최적화

  • 빠른 접근: 싱글톤 빈은 애플리케이션 시작 시 한 번만 생성되므로, 이후의 요청에서는 빈에 대한 빠른 접근이 가능합니다. 이는 인스턴스 생성 오버헤드 없이 빠른 응답 시간을 보장합니다.

4. 일관성 있는 구성 요소 사용

  • 일관된 구성 요소: 모든 컴포넌트가 동일한 인스턴스를 공유함으로써 애플리케이션 전반에 걸쳐 일관된 구성 요소를 사용할 수 있습니다. 이는 애플리케이션의 일관성과 예측 가능성을 향상시킵니다.

5. 통합 관리 및 모니터링 용이성

  • 중앙 집중식 모니터링 및 관리: 싱글톤 빈은 애플리케이션의 중요한 부분을 구성하기 때문에, 중앙에서 모니터링 및 관리하기가 용이합니다. 이는 운영 효율성을 높이고, 문제 해결을 용이하게 합니다.

 

 

이와 반대되게 Prototype Scope는 싱글톤이 아닌 bean 객체를 *DI시에 새로 객체를 생성하게 해줍니다.

더보기
Dependency Injection, DI
객체가 직접 자신의 의존성을 생성하거나 관리하지 않고, 외부의 도움으로 필요한 의존성을 주입받아 사용하게 합니다.


결합도 감소: 객체가 자신의 의존성을 생성하거나 검색하는 대신 주입받음으로써, 클래스 간의 결합도를 줄이고 유연성을 높입니다.
코드 재사용성 향상: 의존성을 외부에서 주입받기 때문에, 다양한 환경이나 상황에서 동일한 컴포넌트를 재사용하기 쉬워집니다.
테스트 용이성: 실제 구현 대신 모의 객체(mock)나 스텁(stub) 등을 주입하여, 단위 테스트(unit test)가 용이해집니다.
유지보수성 향상: 의존성이 명시적으로 드러나므로, 시스템의 다양한 부분을 이해하고 수정하는 데 도움이 됩니다.

 

여기서 궁금했던게 앞서 설명한 것과 같이 싱글톤 패턴으로 얻을 수 있는 이점이 있는데,

Prototype Scope로 객체를 생성했을 때는 어떤 상황이 있을 지 궁금했습니다.

 

Prototype Scope는  주로 빈(bean)의 상태를 유지해야 하거나, 리소스 사용량이 많은 빈을 사용할 때 유용합니다.

 

상태를 유지하는 Bean

사용자의 요청마다 사용자별 작업 상태를 유지해야 하는 웹 애플리케이션

@Component
@Scope("prototype")
public class UserTask {
    private String taskId;
    private Map<String, Object> taskState = new HashMap<>();

    public UserTask() {
        this.taskId = UUID.randomUUID().toString();
    }

    public void addTaskDetail(String key, Object value) {
        taskState.put(key, value);
    }

    // taskId와 taskState의 getter 메서드
}
@Service
public class TaskService {

    @Autowired
    private ApplicationContext context;

    public UserTask createUserTask() {
        return context.getBean(UserTask.class);
    }
}

 

리소스 사용량이 많은 Bean

대용량 파일 처리나 복잡한 계산 작업을 요청마다 수행해야 하는 경우

@Component
@Scope("prototype")
public class HeavyResourceProcessor {
    private HeavyResource resource;

    public HeavyResourceProcessor() {
        // 리소스 집약적인 초기화 작업
        this.resource = new HeavyResource();
    }

    public void process() {
        // 복잡한 리소스 처리 로직
    }
}
@Service
public class ProcessingService {

    @Autowired
    private ApplicationContext context;

    public void processTask() {
        HeavyResourceProcessor processor = context.getBean(HeavyResourceProcessor.class);
        processor.process();
    }
}

 

위 두가지 예시에서 Singleton bean을 사용하는 것보다 Prototype Bean을 사용하는 것이 이점을 가져갈 수 있습니다.

하지만 Prototype Bean을 사용할 때 주의할 점이 있습니다.

 

의존성 주입: 프로토타입 빈을 주입받는 경우, 주입 시점에만 새로운 인스턴스가 생성되며, 이후에는 동일한 인스턴스를 계속 사용합니다. 따라서, 매번 새로운 인스턴스가 필요할 경우 ApplicationContext를 통해 직접 요청해야 합니다.

빈의 생명주기 관리: 프로토타입 스코프 빈은 스프링 컨테이너가 생성과 의존성 주입 후의 생명주기를 관리하지 않습니다. 생성된 빈의 후처리가 필요한 경우, 개발자가 직접 관리해야 합니다.

리소스 leak: 프로토타입 빈을 사용할 때는 생성된 인스턴스의 참조를 적절히 해제하여 리소스 누수가 발생하지 않도록 주의해야 합니다.

 

 

728x90
반응형
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함
250x250