스프링 없이 순수 자바코드로 싱글톤 객체 만들어보기
//싱글톤 객체 만들기
public class SingletonService {
//static영역에 객체 인스턴스 생성
private static final SingletonService instance =
new SingletonService();
public static SingletonService getInstance(){
return instance;
}
//생성자를 private으로 만들어서 외부에서는 객체가 생성되지 않도록 만든다
private SingletonService(){}
public void singletonCall(){
System.out.println("싱글톤 객체 호출");
}
}
SingletonServiceTest test 코드 작성
@Test
@DisplayName("싱글톤 패턴 적용한 객체 사용")
void SingletonServiceTest(){
SingletonService st1 = SingletonService.getInstance();
SingletonService st2 = SingletonService.getInstance();
System.out.println("st1 = " + st1);
System.out.println("st2 = " + st2);
//same 은 ==과 동일
Assertions.assertThat(st1).isSameAs(st2);
}
test 통과와 함께 동일한 객체가 출력된 것을 확인할 수 있다.
스프링 컨테이너를 사용하면 기본적으로 모든 객체를 싱글톤으로 만들어 관리해주기 때문에 위의 코드처럼 번거로운 과정을 거쳐 코드를 작성할 필요가 없다.
매번 고객의 요청이나 필요에 따라 새로운 객체를 생성할 필요 없이 이미 한번 만들어진 객체를 반복해서 사용하기 때문에 성능 문제를 해결할 수 있고 효율성도 높아진다.
private static final SingletonService instance = new SingletonService();
public static SingletonService getInstance(){
return instance; }
private SingletonService(){}
스프링 컨테이너를 사용하지 않는다면 매번 static 영역에 객체를 생성하고 생성자를 private으로 만들어서 외부에서 객체를 생성할 수 없도록 막아주는 코드를 작성해야 한다. 이런식으로 매번 작성하면 비효율적이다.
스프링 컨테이너는 스프링 빈으로 등록된 객체 클래스를 싱글톤으로 생성해서 관리해주기 때문에 위에서 살펴본 싱글톤 패턴의 문제점을 효율적으로 해결해준다.
@Configuration
public class AppConfig {
@Bean
public MemberService memberService(){
return new MemberServiceImpl(memberRepository());
}
@Bean
public OrderService orderService(){
return new OrderServiceImpl(memberRepository(), discountPolicy());
}
위의 코드에서 보면 bean으로 등록된 객체들을 스프링 컨테이너에서 싱글톤으로 관리한다.
스프링 컨테이너는 싱글톤 컨테이너 역할을 하며 싱글톤 객체를 생성하고 관리하는 기능을 싱글톤 레지스트리라고 한다.
@Test
@DisplayName("스프링 컨테이너와 싱글톤")
void springContainer(){
// AppConfig appConfig = new AppConfig();
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
MemberService memberService1 = ac.getBean("memberService", MemberService.class);
MemberService memberService2 = ac.getBean("memberService", MemberService.class);
System.out.println("memberService1 = " + memberService1);
System.out.println("memberService2 = " + memberService2);
Assertions.assertThat(memberService1).isSameAs(memberService2);
}
스프링 컨테이너를 생성해서 객체를 조회해보면 하나의 동일한 객체가 출력되는 것을 확인할 수 있다.
동일한 객체를 반복해서 생성하는 것이 아니라 한번 생성된 객체를 공유하는 것을 확인할 수 있다.
이 글은 김영한님의 스프링 핵심 원리 강의를 듣고 정리한 내용입니다.