일반적인 자바 프로그래밍
웹은 보통 여러 고객이 동시에 요청을 한다.
일반적인 자바 프로그래밍에서는 고객이 요청을 할 때마다 객체를 생성(new)한다.
memberServiceImpl()을 리턴해주는 memberService 객체를 두 개 만들어서(new) 출력해보자.
각 memberService 객체를 보면 서로 다른 두 개가 생성이 된 것을 확인할 수 있다.
문제점
MemberService 객체를 생성할 때 MemberServiceImpl 객체만 생성하는 것이 아니라 MemberServiceImpl의 인자 값으로 넘겨준 memberRepository()에서의 MemoryMemberRepository() 또한 생성되기 때문에 고객의 요청이 들어올 때 마다 2개의 객체가 생성된다고 볼 수 있다.
트래픽이 늘어날수록 감당하기 힘들어진다.
싱글톤
그럼 어떻게 해결해야 할까?
간단하다. 객체를 한 개만 생성하면 된다!
위 코드를 보면 MemberServiceImpl은 MemberRepository 객체를 인자로 받아서 memberRepository 필드 값에 저장하여 join()과 findmember() 함수로 접근할 수 있게 만들었다.
반면에 싱글톤 패턴을 적용한 코드를 보면 생성자에서 인자를 받아서 접근하는 것이 아니라, 생성자는 private으로 혹시 모를 추가적인 객체 생성(new)을 막고 미리 만들어둔 필드의 SingletonService 객체를 getInstance()로 반환해 준다.
위와 동일하게 두 개의 SingletonService 객체를 생성해서 getInstance()로 객체를 받고 출력해보면,
이처럼 두 개의 객체가 같은 instance를 반환해준 것을 확인할 수 있다.
기존의 코드들을 getInstance로 가져다 쓰는 방식으로 바꾸면 되지만 그렇게 할 필요가 없다.
스프링 컨테이너를 사용하면 기본적으로 객체를 모두 싱글톤으로 만들어서 관리해 준다.
위의 방식처럼 객체를 미리 생성해두는 방식 외에도 싱글톤 패턴을 적용하는 방법은 여러 가지 있지만 객체 생성하는 데에 메모리를 많이 잡아먹지 않는 이상 로딩할 때 만들어 두는 것이 가장 편하고 안전하다.
싱글톤 패턴의 문제점
이렇게 완벽해 보이는 싱글톤 패턴에도 많은 문제점이 있다.
- 싱글톤 패턴을 구현하는 코드 자체가 많이 들어간다.
- 의존관계상 클라이언트가 구체 클래스에 의존한다. -> DIP 위반
- 클라이언트가 구체 클래스에 의존해서 OCP 원칙을 위반할 가능성이 높다.
- 테스트하기 어렵다.
- 내부 속성을 변경하거나 초기화 하기 어렵다.
- private 생성자로 자식 클래스를 만들기 어렵다.
- 결론적으로 유연성이 떨어진다.
- 안티패턴으로 불리기도 한다.
이런 문제점들을 모두 해결해 주는 것이 스프링이다.
싱글톤 컨테이너
스프링 컨테이너는 싱글톤 패턴의 문제점을 해결하면서, 객체 인스턴스를 1개만 생성하면서 관리한다.
스프링 빈이 바로 싱글톤으로 관리되는 빈이다.
- 스프링 컨테이너는 싱글톤 패턴을 적용하지 않아도 객체 인스턴스를 싱글톤으로 관리한다.
- 스프링 컨테이너는 싱글톤 컨테이너 역할을 한다. 이렇게 싱글톤 객체를 생성하고 관리하는 기능을 싱글톤 레지스트리라고 한다.
이런 기능 덕분에 싱글톤 패턴의 모든 단점을 해결할 수 있다.
- 지저분한 코드가 들어가지 않아도 된다.
- DIP, OCP, 테스트, private 생성자로부터 자유롭게 싱글톤을 사용할 수 있다.
'BE > Spring Boot' 카테고리의 다른 글
REST API와 flutter sdk를 이용한 카카오 로그인의 차이점 (0) | 2022.07.07 |
---|---|
의존관계 주입 (2) | 2022.03.20 |
싱글톤 방식의 주의점 (0) | 2022.03.20 |
좋은 객체 지향 설계의 5가지 원칙(SOLID) (0) | 2022.03.11 |
의존성 주입 (Dependency Injection) (0) | 2022.02.22 |