싱글톤 컨테이너

inho ha·2022년 4월 14일
0

스프링 핵심 원리

목록 보기
3/7

김영한님의 강의를 들으면서 필기한 내용입니다.

싱글톤

웹 어플리케이션은 보통 여러 고객이 동시에 요청한다

그럼 DI 컨테이너(AppConfig)는 Service 객체를 new로 여러개 만들어서 리턴해주는가?

스프링 없이 순수 자바 코드로 실행시 Service 객체를 appConfig 에서 가져올때 new로 생성해서 리턴해준다
뿐만 아니라 의존관계에 있는 다른 객체로 모두 새로 생성된다
객체를 get 하는 것의 비용이 1이라면 생성하는 것의 비용은 1000 이상
-> 메모리 낭비가 심하다

해결 방안 -> 객체를 하나 생성해서 공유하도록 설정

싱글톤 패턴

클래스의 인스턴스가 딱 1개만 생성되는 것을 보장하는 디자인 패턴

static 영역에 객체 instance를 미리 하나 생성해서 올려두고
getInstance 메서드를 통해서 인스턴스를 반환 받을 수 있도록 설정
new 로 객체 생성하지 못하도록 private 생성자 작성

스프링 컨테이너를 사용하면 기본적으로 싱글톤 패턴으로 관리해줌

싱글톤 패턴 문제점

코드 작성 많이 해야함

클라이언트가 구체 클래스에 의존하여 DIP를 위반한다
따라서 OCP 원칙 위반 가능성이 높다

테스트하기 어렵다

내부 속성을 변경하거나 초기화하기 어렵다

private 생성자로 자식 클래스를 만들기 어렵다

결국 유연성이 떨어져서 안티패턴으로 불리기도 함

-> 그러나 스프링은 이 문제점 다 해결하고 싱글톤으로 관리해줌

싱글톤 컨테이너

스프링 빈이 싱글톤으로 관리되는 빈이다
스프링 컨테이너는 config 파일을 읽어서 스프링 빈 저장소에 빈 객체를 저장해두고 필요시 리턴해준다

싱글톤 방식의 주의점

싱글톤 방식은 여러 클라이언트가 같은 객체 인스턴스를 공유하기 때문에 상태를 유지하게(stateful) 하게 설계하면 안된다

무상태(stateless)로 설계 해야한다

특정 클라이언트에 의존적인 필드가 있으면 안된다
특정 클라이언트가 값을 변경할 수 있는 필드가 있으면 안된다
가급적 읽기만 가능해야한다
필드 대신에 자바에서 공유되지 않는 지역변수, 파라미터, threadLocal 등을 사용해야한다.

스프링 빈 필드에 공유 값을 설정하면 큰장애 발생 가능 (몇년에 한번씩 꼭 발생함 항상 조심하고 항상 겸손해라 깝죽거리지 마라)

@Configuration과 싱글톤


appConfig 코드를 보면 memberService() 호출시 MemberServiceImpl을 new로 생성하고 있고 memberRepository()는 MemoryMemberRepository를 new 로 생성하고 있다

-> 싱글톤이 아닌거 아냐??

응 아니야

객체들은 한번씩만 생성되고 있음

@Configuration과 바이트코드 조작

스프링 빈에서 appConfig를 가져와서 출력해보면 클래스 명 뒤에 다른 문자가 더 붙어 있다

스프링은 CGLIB 내부 기술을 사용하여 appConfig를 상속받고 싱글톤이 보장 되도록 수정하여 구현하여 빈에 저장한다

new 로 생성시 if로 이미 스프링 빈이 존재하는지 확인하고 있으면 반환 없으면 생성해서 빈에 등록후 반환하도록 구현한다

@Configuration을 붙이지 않고 @Bean만 붙이면 싱글톤이 깨진다

profile
iha / ian / inho ha

0개의 댓글