반응형
4. 싱글톤 컨테이너
1. java는 웹 애플리케이션 서비스 용 언어
- 요청이 있을 때마다 새로 new 를 해서 객체를 반환하는 문제
- 클라이언트가 요청할 때 매번 객체가 새로 생긴다
- 요청을 수행하기 위해 스레드가 하나 생기고, 독립적인 인스턴스가 생기기 때문에 그런 것이다.
2. 싱글톤 패턴
- 싱글톤 패턴을 이용하여, 하나의 객체를 가지고 요청을 처리하도록 할 수 있다.
- 생성자 private 화, 그리고 static 멤버 변수로 미리 생성해둔 후 getInstance() 로 반환.
3. 싱글톤 패턴의 문제점
- 싱글톤 패턴을 구현하는데 코드를 많이 필요로 한다.
- 의존관계상 클라이언트가 구현체에 의존하게 된다. DIP 위반
- 따라서 OCP 도 위반하게 된다.
- 유연한 테스트를 하기 어렵다.
- 내부 속성을 변경하거나 초기화하기 어렵다.
- private 생성자를 사용하므로 자식 클래스를 생성하기 어렵다.
- 결과적으로 효율적인 코드를 작성하기 어렵다.
- 안티패턴으로도 불린다.
4. 싱글톤 컨테이너
- 스프링 컨테이너는 위의 싱글톤 패턴의 문제를 모두 해결하면서도, 싱글톤 컨테이너를 유지한다.
- 스프링 컨테이너가 생길 때 모든 스프링 빈을 등록한다.
- 이렇게 빈을 생성하고 등록하는 것을 싱글톤 레지스트리라고 부른다.
- 이렇게 함으로써 OCP, DIP, 테스트, private 생성자로부터 자유로워지게 된다. (직접 코드를 작성하지 않아도 됨.)
- 스프링 컨테이너가 생길 때 모든 스프링 빈을 등록한다.
- 싱글톤 방식의 주의점 (매우 중요한 내용!)
- 여러 클라이언트가 하나의 객체 인스턴스에 의존하기 때문에 상태를 유지하면 안된다.
- stateless 컨테이너로 만들어야 한다.
- 특정 클라이언트에 의존적인 필드가 있으면 안된다.
- 특정 클라이언트가 값을 변경할 수 있는 필드가 있어서는 안된다.
- 가급적 읽기만 가능해야 한다.
- 필드 대신 자바에서 공유되지 않는 지역변수, 파라미터, ThreadLocal 등을 사용해야 한다.
- 발생하는 문제
- 나의 아이디로 다른 사람의 결제 내역이 보이는 문제 발생
- @Configuration
- @Configuration 어노테이션이 붙은 AppConfig는 어떻게 동작하는 걸까?
- 각 객체를 등록하기 위해 메소드를 호출하면, new MemoryMemberRepository() 는 여러번 호출된다.
- meberServiceImpl, orderServiceImpl 에서 모두 memberRepository()를 호출하기 때문이다.
- 각 객체를 등록하기 위해 메소드를 호출하면, new MemoryMemberRepository() 는 여러번 호출된다.
- @Configuration 어노테이션이 붙은 AppConfig는 어떻게 동작하는 걸까?
- @Configuration과 바이트 코드
- AppConfig 클래스를 전달하고 ApplicationContext 구현체 즉 컨테이너가 만들어질 때, CGLIB 라이브러리를 활용해서 AppConfig@CGLIB 클래스가 만들어진다.
- CGLIB : 바이트코드 조작 라이브러리
- AppConfig@CGLIB : AppConfig를 상속한 자식 클래스.
- 메소드 호출 시, 이미 등록된 빈이라면 등록된 빈을 반환하고 그렇지 않으면 기존 로직을 호출해서 반환된 객체를 등록하고 반환하는 로직을 수행할 것이다.
- @Configuration이 없으면, AppConfig@CGLIB 이 아니라 AppConfig를 통해서 빈 등록이 되는데, 싱글톤으로 관리가 되지 않고 기존 코드가 매번 호출되면서 새로운 객체가 등록된다.
- 따라서 각 객체가 참조하는 memberRepository 는 애초에 스프링 컨테이너가 관리하는 빈이 아닌 것이다.
반응형
'개발 > java' 카테고리의 다른 글
[Spring 기본] 6. 의존관계 자동 주입 (1) | 2024.01.06 |
---|---|
[Spring 기본] 5. 컴포넌트 스캔 (0) | 2024.01.06 |
[Spring 기본] 3. Spring 프레임워크 사용하기 (1) | 2023.12.21 |
Input 찬찬히 뜯어보기. (BufferedReader와 InputStreamReader?) (0) | 2023.12.11 |
[Spring 기본] 2. 실제 코드에서의 스프링 프레임워크 핵심 원리 (0) | 2023.12.08 |