[Spring] 5-1. 웹 애플리케이션과 싱글톤

송광호·2023년 12월 21일

[Spring]

목록 보기
21/41
post-thumbnail

Spring 시리즈는 혼자 공부하며 기록으로 남기고, 만약 잘못 학습 한 지식이 있다면 공유하며 피드백을 받고자 작성합니다.
스프링에 대해 깊게 공부해보고자 인프런의 김영한 강사님께서 강의를 진행하시는 (스프링 핵심 원리 - 기본편) 강의를 수강하며 정리하는 글입니다.
혹여나 글을 읽으시며 잘못 설명된 부분이 있다면 지적 부탁드리겠습니다.


웹 애플리케이션과 싱글톤

  • 스프링은 왜 탄생했는지 물어본다면 기업용 온라인 서비스 기술을 지원하기 위해 만들어졌다
  • 대부분의 스프링 애플리케이션은 웹 애플리케이션이다.
    • 물론 웹이 아닌 애플리케이션도 얼마든지 개발이 가능하다.
  • 웹 애플리케이션은 보통 여러 고객이 동시에 요청을 한다.
  • 웹 애플리케이션은 고객이 계속 요청을 하는 애플리케이션이다.
    • 계속 요청이 올때마다 객체를 계속 만들고있다. - 문제점

스프링 없는 순수한 DI 컨테이너 테스트

public class SingletonTest {

    @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);

        //memberService != memberService2
        Assertions.assertThat(memberService1).isNotSameAs(memberService2);
    }
}
  • 기존에 만들었던 스프링 없는 AppConfig는 요청을 할 때 마다 객체를 새로 생성한다.
  • 만약 트래픽이 많다면? 트래픽이 많은만큼 초당 객체가 생성되고 소멸된다. -> 메모리 낭비로 이어진다.
  • 해결방안
    • 해당 객체를 딱 1개만 생성하고, 공유하도록 설계한다. -> 싱글톤

싱글톤 패턴

  • 클래스의 인스턴스가 딱 1개만 생성되는 것을 보장하는 GoF 디자인 패턴중 생성 패턴에 해당한다.
  • 따라서 객체가 2개이상 생성되지 못하도록 private 생성자를 사용하여 추가적인 생성을 제한해야 한다.

싱글톤 패턴 코드

public class SingletonService {

    //1. static 영역에 객체를 딱 1개만 생성한다.
    private static final SingletonService instance = new SingletonService();
    
    //2. public으로 열어서 객체 인스턴스가 필요하면 이 static 메서드를 통해서만 조회하도록 허용한다.
    public static SingletonService getInstance() {
        return instance;
    }


    //3. private 생성자를 사용하여 다른곳에서 생성 제한한다.
    private SingletonService() {
    }

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

    public static void main(String[] args) {

    }
}
    1. static 영역에 객체를 딱 1개만 생성해둔다.
    1. 만약 이 객체가 필요하다면 getInstance()메서드를 통해서만 조회해야한다.
      이 메서드를 호출하면 항상 같은 인스턴스를 반환한다.
    1. 딱 1개의 인스턴스만 존재해야하기때문에 생성자는 private로 막아서 외부에서 new 를 통해 생성되는 것을 막아야한다.

싱글톤 패턴 사용 테스트 코드

public class SingletonTest {

    @Test
    @DisplayName("싱글톤 패턴을 적용한 객체 사용")
    void singletonServiceTest() {
    
        //1. 조회 : 호출할 때 객체를 반환
        SingletonService instance1 = SingletonService.getInstance();
        //2. 조회 : 한번 더 똑같이 호출하면 같은 객체를 반환
        SingletonService instance2 = SingletonService.getInstance();
		
        //참조값이 같은지 확인
        System.out.println("instance1 = " + instance1);
        System.out.println("instance2 = " + instance2);
		
        //instance1 == instance2 만족하는지?
        assertThat(instance1).isSameAs(instance2);
        
        singletonService1.logic();
    }
}
  • 생성은 private 로 막혀있기 때문에 getInstance()메서드를 사용하여 객체를 반환받아야한다.
  • 호출받을때마다 같은 객체를 반환받는다.

참고: 싱글톤 패턴을 구현하는 방법은 여러가지가 있지만, 여기서는 객체를 미리 생성하고 또다른 생성을 막아두는 가장 단순하고 안전한 방법을 선택해서 구현하였다.

싱글톤 패턴 문제점

  • 일단 싱글톤 패턴을 구현하는 코드 자체가 많이 들어간다.
  • 클라이언트가 구체 클래스에 의존하기 때문에 DIP를 위반한다.
    • 구체 클래스에 의존하기 때문에 OCP를 위반할 가능성이 높다.
  • 테스트, 내부속성 변경 및 초기화, private 생성자로인한 자식 클래스의 생성이 어렵다.
    • 결론적으로 유연성이 낮아진다.
  • 안티패턴이라고 불리기도 한다.

다음 학습
위와 같은 단점들이 존재하는데 저런 단점들을 끌어안고 사용 할 가치가 있는가? 라고 생각한다면
싱글톤 컨테이너 라는게 존재한다.

0개의 댓글