해당 포스팅은 김영한 님의 인프런 강의 "스프링 핵심 원리 - 기본편" 을 통해 얻은 지식을 정리한 자료 입니다.
[참고 자료]
1. 싱글톤(Singleton)
: 싱글톤은 디자인 패턴으로 "클래스의 인스턴스가 딱 1개만 생성되는 것을 보장하는 디자인 패턴" 이다.
* 싱글톤을 왜 써야 하는가?
여러 클라이언트로 부터 막대한 양의 요청이 오게될 경우, 요청 때 마다 객체 인스턴스를 생성하여 반환하게 된다면,
1. 애플리케이션 성능 저하
2. 메모리 낭비 심화
3. 비용 과다 (객체 인스턴스를 생성하는 비용은 참조로 가져오는 비용보다 압도적으로 높다.)
등의 약점이 존재한다.
따라서, 해당 클래스의 인스턴스를 딱 1개만 생성하여, 요청시에 해당 인스턴스의 참조값을 반환하는 것이 유리하다.
스프링 컨테이너는 스프링 빈을 기본적으로 싱글톤 방식을 통해 관리한다.
2. 스프링 컨테이너 와 싱글톤(Singleton)
<AppConfig.class>
* 스프링 없는 순수한 DI 컨테이너 (스프링 컨테이너 X)
스프링 컨테이너를 사용하지 않고, 'AppConfig.class' 로 같은 타입의 객체 인스턴스를 2개 생성하였다.
<출력값>
서로 다른 객체 인스턴스가 생성 된 것을 볼 수 있다.
이는 싱글톤이 적용되지 않았음을 알 수 있다.
* 스프링 컨테이너가 관리하는 객체 인스턴스 (스프링 빈)
스프링 컨테이너가 관리하는 같은 이름, 같은 타입의 스프링 빈을 2번 조회하였다.
<애플리케이션 스프링 빈 생성>
<출력값>
같은 객체 인스턴스가 조회 된 것을 볼 수 있다.
[스프링 없는 순수한 DI 컨테이너] 의 경우,
클라이언트 요청시 마다, 객체 인스턴스를 생성하여 반환한다.
(싱글톤이 적용되어 있지 않음.)
[스프링 컨테이너] 의 경우,
클라이언트 요청시, 이미 생성되어 있는 딱 1개의 객체 인스턴스의 참조를 반환한다.
(싱글톤이 적용되어 있음.)
[+ 참고]
@Configuration 어노테이션
<AppConfig.class>
@Bean memberService -> new MemberServiceImpl() -> memberRepository -> new MemoryMemberRepository()
@Bean orderService -> new OrderSerivceImpl() -> memberRepository -> new MemoryMemberRepository()
@Bean memberRepository -> new MemoryMemberRepository()
이렇게 빈을 생성하기 위해 "new MemoryMemberRepository()" 가 3번 호출 된다.
객체 인스턴스가 딱 1개만 생성되는 싱글톤에 위배되는 것 아닐까?
결론 부터 말하자면, 싱글톤은 위배되지 않는다.
스프링 빈은 위와 같이 생성된다.
여기서 중요한 부분은 스프링 빈으로 생성된 'appConfig' 이다.
다른 4가지 빈은 @Bean 어노테이션을 통해 스프링 빈으로 관리된다.
'appConfig' 는 @Configuration 어노테이션이 붙은 'AppConfig.class' 인데, 이것도 스프링 빈으로 관리된다.
순수 클래스명이 출력되는 것이 아니라, 클래스 명 뒤에 'EnhancerBySpringCGLIB' 가 붙어 있다.
이는 'CGLIB' 라는 바이트 조작 라이브러리를 사용해서 AppConfig 클래스를 상속 받은 임의의 다른 클래스를 만들고, 해당 클래스를 스프링 빈으로 등록한 것이다.
CGLIB 에게 "new MemoryMemberRepository()"를 요청한다면...
(미리 만들어 두는 것이 아닌 해당 객체의 실행 시점에 생성)
IF) 기존에 생성해둔 객체 인스턴스가 존재하는가?
- YES) 기존에 생성해둔 객체 인스턴스의 참조값을 반환
- NO) 객체 인스턴스 생성
이와 같은 과정을 통해, 스프링 컨테이너는 싱글톤을 위배하지 않는다.
'Spring' 카테고리의 다른 글
[Spring + API] 컬렉션 엔티티를 조회 + 페이징 (0) | 2024.01.01 |
---|---|
[Spring] ComponentScan (컴포넌트 스캔) (0) | 2023.11.18 |
[Spring] 스프링 빈 생성과정 / 스프링 빈 구성 정보 파일 지원 과정 (0) | 2023.11.10 |
[Spring] 스프링 빈 조회 테스트(이름 / 타입 / 중복 조회) (0) | 2023.11.07 |
[Spring] 순수 JAVA 코드에서 Spring으로 전환하기 (1) | 2023.11.06 |