티스토리 뷰
서론
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: 프로토타입 빈을 사용할 때는 생성된 인스턴스의 참조를 적절히 해제하여 리소스 누수가 발생하지 않도록 주의해야 합니다.
'Back End > Spring' 카테고리의 다른 글
[Spring] Feign Client - (2) logger, interceptor, error decoder (1) | 2024.02.22 |
---|---|
[Spring] Feign Client - (1) Naver API 호출하기 (0) | 2024.02.18 |
[Spring] Spring에서 Proxy 객체를 사용하는 경우 (0) | 2024.02.15 |
[Web MVC] API 만들기(request) - 2 (0) | 2023.03.06 |
[Web MVC] API 만들기 - 1 (0) | 2023.03.06 |
- Total
- Today
- Yesterday
- cs
- zookeeper
- centos
- KAFKA
- spring boot
- logback
- React
- Producer
- Linux
- Firebase
- K8S
- consumer
- spring
- Data Engineering
- API
- NextJS
- apache
- 프론트엔드
- Container
- JPA
- Front
- frontend
- rhel
- broker
- docker
- OS
- apache kafka
- 리액트
- Java
- feign client
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |