이번 챕터는 머릿속에 잘 정리했기 때문에 여긴 메모만 아무렇게나 했다.
∨ 웹애플리케이션은 고객 요청이 끊임없이 들어옴
: 그때마다 새로운 객체를 생성하는건 좋지 X
: 트래픽↑면 메모리효율↓↓↓↓
∴ 싱글톤
예제
public class SingletonService {
// static 영역에 객체 instance를 하나 생성해서 올려둔다.
private static final SingletonService instance = new SingletonService();
// 이 객체 인스턴스가 필요하면 오직 getInstance() 통해서만 조회 가능
// 매번 같은 인스턴스 반환
public static SingletonService getInstance() {
return instance;
}
// 외부에서 new 생성 불가능하게 private 지정
private SingletonService() {
}
public void logic() {
System.out.println("싱글톤 객체 로직 호출");
}
}
∨ Test
@Test
@DisplayName("싱글톤 패턴을 적용한 객체 사용")
void singletonServiceTest() {
SingletonService singletonService1 = SingletonService.getInstance();
SingletonService singletonService2 = SingletonService.getInstance();
assertThat(singletonService1).isSameAs(singletonService2);
}
참고)
@Test
@DisplayName("스프링 없는 순수한 DI 컨테이너")
void pureContainer() {
AppConfig appConfig = new AppConfig();
MemberService memberService1 = appConfig.memberService();
MemberService memberService2 = appConfig.memberService();
// mS1 != mS2
assertThat(memberService1).isNotSameAs(memberService2);
}
∨ 스프링 컨테이너 쓰면 객체를 싱글톤으로 관리해줌!
: 이때 싱글톤패턴의 단점은 모두 제거됨
- 코드 지저분해짐
- 구체클래스 의존 - DIP위반 -> OCP위반
- Test 어려워짐
- 변경어려워짐
- private 생성자 -> 자식클래스 만들기 어렵
● 그런데 스프링 컨테이너를 이용하면
사실 안티패턴이기도 한 이러한 싱글톤 패턴의 단점을 모두 해결한 싱글톤을 사용가능하다는 거
∨ Test
@Test
@DisplayName("스프링 컨테이너와 싱글톤")
void springContainer() {
ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
MemberService memberService1 = ac.getBean("memberService", MemberService.class);
MemberService memberService2 = ac.getBean("memberService", MemberService.class);
assertThat(memberService1).isSameAs(memberService2);
}
![](https://blog.kakaocdn.net/dn/k01gi/btrGPoMaP1q/dK76b1lYanI8Ajb3S4THo0/img.png)
∨ 스프링 컨테이너에서 싱글톤만 지원하는 건 아니다
그러나 거의 대부분 싱글톤으로 쓸 일만 있다고 한다.
99.9%라고 하셨다.
∨ 싱글톤 방식의 주의점
- 객체는 상태를 유지하게 설계하면 안된다 (stateful X)
- 무상태(stateless)로 설계해야 함
- 가급적 읽기만 가능해야 함
- 필드 대신에 지역변수/파라미터/ThreadLocal등을 사용
- 스프링 빈 필드에 공유값을 설정하면 아쥬아쥬 큰 장애 발생 가능 주의
∨ @Configuration과 싱글톤
이 어노테이션이 싱글톤을 보장한다.
▽ 쭉 보면 공부했던 게 생각날 것임
- AppConfig <- AppConfig@CGLIB
(바이트코드조작라이브러리, 스프링빈으로등록되는건새로만들어진상속받은클래스)
- 그래서 @Bean 메서드마다 : 빈존재하면리턴, 빈존재안하면생성
=> 그래서 repository print문이 1번만 출력되는 것을 볼 수 있었음
- @Configuration 안쓰면 그냥 클래스 AppConfig를 사용 & 싱글톤보장X
- @Bean을 빈으로 등록하기는 하지만 싱글톤X
- 고민할 것 없이 설정정보는 항상 @Configuration
끗끗
'web +a' 카테고리의 다른 글
자동주입 - 옵션 처리 (0) | 2022.07.11 |
---|---|
컴포넌트 스캔 (0) | 2022.07.08 |
스프링 빈 조회 (getBean) - 상속관계인 경우 (0) | 2022.07.06 |
(컨테이너에 등록된) 스프링 빈 조회해보기 (0) | 2022.07.06 |
스프링 컨테이너 첫 이용 (0) | 2022.07.05 |