728x90
싱클톤 패턴
package singleton;
import com.changddao.fall_in_spring.AppConfig;
import com.changddao.fall_in_spring.member.MemberService;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
public class SingletonTest {
@Test
@DisplayName("스프링 없는 순수한 DI 컨테이너")
void pureContainer() {
//given
AppConfig appConfig = new AppConfig();
//when
//1. 조회: 호출할 때 마다 객체를 생성
MemberService memberService1 = appConfig.memberService();
//2. 조회: 호출할 때 마다 객체를 생성
MemberService memberService2 = appConfig.memberService();
//that
System.out.println("memberService1 = " + memberService1);
System.out.println("memberService2 = " + memberService2);
//memberService1 != memberService2
Assertions.assertThat(memberService1).isNotSameAs(memberService2);
}
}
- 스프링이 없는 순수한 DI 컨테이너인 AppConfig는 요청을 할 때 마다 객체를 새로 생성한다.
- 고객 트래픽이 초당 100이 나오면 초당 100개 객체가 생성되고 소멸된다!
메모리 낭비가 심하다.
- 해결방안은 해당 객체가 딱 1개만 생성되고, 공유하도록 설계하면 된다. -> 싱글톤 패턴
그래서 싱글톤 패턴 어떻게 사용하는데?
- 클래스의 인스턴스가 딱 1개만 생성되는 것을 보장하는 디자인 패턴이다.
- 객체 인스턴스를 2개 이상 생성하지 못하도록 막아야 한다.
-> private 생성자를 사용해서 외부에서 임의로 new 키워드를 사용하
지 못하도록 막아야 한다.
package singleton;
public class SingletonService {
private static final SingletonService instance = new SingletonService();
public static SingletonService getInstance(){
return instance;
}
private SingletonService(){
}
}
- SingletonService의 생성자를 private으로 선언하여 외부에서 접근하지 못하도록 막고, 내부에서 static으로 선언된 getInstance를 이용하여 객체를 호출한다.
너무나도 당연하겠지만 SingletonService에서 getInstance메소드를 호출한 객체가 같은지 비교해보자
@Test
@DisplayName("싱글톤 패턴을 적용한 객체 사용")
void singletonService() {
//given
//오류 발생
/*SingletonService singletonService = new SingletonService(); //*/
//when
SingletonService service1 = SingletonService.getInstance(); // 이런식으로 싱글톤 사용
SingletonService service2 = SingletonService.getInstance(); // 이런식으로 싱글톤 사용
// that
Assertions.assertThat(service1).isEqualTo(service2);
}
테스트결과
-> 싱글톤 패턴을 이용하면 불필요한 자원 낭비를 막을 수 있다. 물론 garbage collection이 많은 객체들이 쌓였을 때, 잘 처리를 해주겠지만 사전에 불필요한 객체 생성을 막을 수 있기에 싱글톤 패턴을 이용하는 것은 매우 합리적이다.
'Spring & SpringBoot' 카테고리의 다른 글
| Spring이용하여 File 업로드 하기 및 File Download(1) (0) | 2023.12.03 |
|---|---|
| Spring Bean @Validation (2) | 2023.12.03 |
| 스프링 빈의 Life Cycle (1) | 2023.12.02 |
| Spring IoC, DI, 그리고 컨테이너 (0) | 2023.12.02 |
| 좋은 객체지향 설계 원칙 SOLID (1) | 2023.12.02 |