싱글톤 컨테이너

Mina Park·2023년 10월 9일

1. 웹 애플리케이션과 싱글톤

  • 웹 애플리케이션은 보통 여러 고객의 동시요청이 발생함
  • 때문에 요청시마다 새로운 객체 생성을 하는 것은 불가능
    => 해당 객체를 하나만 생성하여 공유하도록 설계 (싱글톤 패턴)

2. 싱글톤 패턴이란?

  • 클래스의 인스턴스가 딱 1개만 생성되도록 보장하는 디자인 패턴
public class SingletonService {

    // 1. static 영역에 객체를 한개만 생성
    private static final SingletonService instance = new SingletonService();

    // 2. public으로 열어서 객체 인스턴스가 필요하면 이 static 메서드를 통해서만 조회하도록 허용
    public static SingletonService getInstance() {
        return instance;
    }

    // 3. 생성자를 private으로 선언해서 외부에서 new 키워드를 사용한 객체 생성을 못하도록 막음
    private SingletonService() {
    }

    public void logic() {
        System.out.println("싱글톤 객체 로직 호출");
    }


}
    @Test
    @DisplayName("싱글톤 패턴을 적용한 객체 사용")
    void singletonServiceTest() {
//        new SingletonService(); 컴파일 오류 발생

        SingletonService singletonService1 = SingletonService.getInstance();
        SingletonService singletonService2 = SingletonService.getInstance();

        //참조값이 같은 것을 확인
        System.out.println("memberService1 = " + singletonService1);
        System.out.println("memberService2 = " + singletonService2);

        assertThat(singletonService1).isSameAs(singletonService2);
    }
    
  • 이렇게 싱글톤 패턴을 구현해두면, 다른 클래스에서 new SingletonService() 로 호출시 컴파일 오류 발생

Q. 싱글톤 패턴은 장점만 있을까?

  • 싱글톤 패턴을 구현하는 코드 자체가 소모적
  • 의존관계상 클라이언트가 구체 클래스에 의존하게되면서 DIP 위반, OCP 원칙 위반 등이 발생등등의 문제점이 존재함

3. 싱글톤 컨테이너

스프링에서는 이러한 싱글톤 패턴의 문제점을 해결하면서 객체 인스턴스를 싱글톤으로 관리할 수 있도록 싱글톤 컨테이너를 제공

1) 싱글톤 컨테이너란?

  • 싱글톤 패턴을 따로 소스로 구현하지 않아도 객체 인스턴스를 자동으로 싱글톤으로 관리해줌
  • 스프링 컨테이너 자체가 싱글톤 컨테이너 역할을 함
 @Test
    @DisplayName("스프링 컨테이너와 싱글톤")
    void springContainer() {
        ApplicationContext 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);

    }

2) 싱글톤 방식의 주의점

  • 객체 인스턴스를 하나만 생성해서 공유하기 때문에, 싱글톤 객체는 stateful하게 설계하면 안됨
  • 무조건 "stateless"로 설계해야 한다
    • 공유 필드 사용금지!!!
    • 자바에서 공유되지 않은 지역변수, 파라미터 등을 사용

0개의 댓글