<인프런의 김영한님의 강의를 보고 정리한 내용입니다>
스프링 컨테이너를 사용하지 않으면 싱글톤이 적용되지 않는다. 간단히 테스트를 해보면,
@Configuration
public class AppConfig {
@Bean
public MemberService memberService() {
return new MemberServiceImpl(memberRepository());
}
@Bean
public MemoryMemberRepository memberRepository() {
return new MemoryMemberRepository();
}
@Bean
public OrderService orderService() {
return new OrderServiceImpl(memberRepository(), discountPolicy());
}
@Bean
public DiscountPolicy discountPolicy() {
// return new FixDiscountPolicy();
return new RateDiscountPolicy();
}
}
@Test
@DisplayName("스프링 없는 순수한 DI 컨테이너")
void pureContainer() {
AppConfig appConfig = new AppConfig();
//1. 조회: 호출할 떄 마다 객체를 생성
MemberService memberService1 = appConfig.memberService();
//2. 조회: 호출할 때 마다 객체를 생성
MemberService memberService2 = appConfig.memberService();
//참조값이 다른 것을 확인
System.out.println("memberService1 = " + memberService1);
System.out.println("memberService2 = " + memberService2);
// memberService1 != memberService2
assertThat(memberService1).isNotSameAs(memberService2);
}
테스트 코드를 작성하고 확인해보면,
다른 인스턴스가 생성된 것을 확인할 수 있다. 이렇게 매번 다른 인스턴스가 생성되면 효율성이 떨어질 것이다. 이런 단점을 해결하기 위해서 싱글톤으로 코드를 작성해야 한다.
public class SingletonService {
private static final SingletonService instance = new SingletonService();
public static SingletonService getInstance() {
return instance;
}
// new 키워드로 외부에서 인스턴스가 생성되는 것을 막음
private SingletonService() {
}
public void logic() {
System.out.println("싱글톤 객체 로직 호출출");
}
}
이런 식으로 적용해서
@Test
@DisplayName("싱글톤 패턴을 적용한 객체 사용")
void singletonServiceTest() {
SingletonService singletonService1 = SingletonService.getInstance();
SingletonService singletonService2 = SingletonService.getInstance();
System.out.println("singletonService1 = " + singletonService1);
System.out.println("singletonService2 = " + singletonService2);
assertThat(singletonService1).isSameAs(singletonService2);
}
테스트를 하면
같은 인스턴스임을 확인할 수 있다. 그런데 이런 싱글톤의 단점은 뭘까?
🎈싱글톤의 문제점
이 문제들을 해결하기 위해 사용하는 것이, 스프링 컨테이너이다. 스프링 컨테이너를 사용하면 이 문제점을 해결해 주는데,
🎁 스프링 컨테이너는 싱글톤 패턴을 적용하지 않아도, 객체 인스턴스를 싱글톤으로 관리한다.
🎁 스프링 컨테이너는 싱글톤 컨테이너 역할을 한다. 이렇게 싱글톤 객체를 생성하고 관리하는 기능을 싱글톤 레지스트리라 한다.
🎁 스프링 컨테이너의 이런 기능으로 싱글톤의 단점을 해결하고 객체를 싱글톤으로 유지할 수 있다.
이제 싱글톤으로 적용됐는지 확인해보면,
@Test
@DisplayName("스프링 컨테이너와 싱글톤")
void springContainer() {
ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
//1. 조회: 호출할 떄 마다 객체를 생성
MemberService memberService1 = ac.getBean("memberService", MemberService.class);
MemberService memberService2 = ac.getBean("memberService", MemberService.class);
//참조값이 다른 것을 확인
System.out.println("memberService1 = " + memberService1);
System.out.println("memberService2 = " + memberService2);
// memberService1 != memberService2
assertThat(memberService1).isSameAs(memberService2);
}
잘 적용된 것을 알 수 있다.
참고로 기본 빈 등록방식은 싱글톤이지만, 다른 방식도 지원한다.
@AllArgsConstructor 유의사항 (0) | 2022.03.12 |
---|---|
[ Spring ] DI 컨테이너 싱글톤 방식의 문제점 (0) | 2022.02.05 |
[ JPA ] Named Query (0) | 2022.02.03 |
[ JPA ] 페치 조인 (fetch join) - 한계 (0) | 2022.02.02 |
[ JPA ] 페치 조인 (fetch join) - 기본 (0) | 2022.02.02 |