스프링 컨테이너가 보장해주는 싱글톤 (1)

심현민·2024년 9월 8일
0

Spring

목록 보기
7/18

스프링은 기업용 온라인 서비스를 지원하기위해 탄생한 웹 애플리케이션이다.

스프링 없는 순수한 DI 컨테이너가 가진 문제점을 보고 스프링과 비교

문제점 : 웹 애플리케이션은 보통 고객이 요청을 하면 요청을 할 때 마다 객체를 만들어야 한다

고객이 각기 다른 요청을 2번 요청했을 때

  @Test
    @DisplayName("스프링 없는 순수한 DI 컨테이너")
    void pureContatiner() {
        AppConfig appConfig = new AppConfig();
        //1. 조회 : 호출할 때 마다 객체를 생성
        MemberService memberService1 = appConfig.memberService();
        //2. 조회 : 호출할 때 마다 객체를 생성
        MemberService memberService2 = appConfig.memberService();

        //참조값이 다른 것을 확인
        System.out.println("memberService1 = " + memberService1);
        System.out.println("memberService2 = " + memberService2);

        assertThat(memberService1).isNotSameAs(memberService2);

    }

AppConfig 내에 객체를 포함하면 고객 요청 2개에 총 4개의 객체가 생성된 것이다. -> 메모리 낭비

해결 방법은 해당 객체가 딱 1개만 생성되고, 공유하도록 설계하면 된다. -> 싱글톤 패턴

그래서 객체 인스턴스를 2개 이상 생성하지 못하도록 막아야 한다.

SingletonService.class

package com.example.demo.singleton;

public class SingletonService {
    private static final SingletonService instance = new SingletonService();
    //내부적으로 자기자신을 생성해서 instance에 참조로 넣어 놓는다.

    public static SingletonService getInstance(){
        return instance;
    }
    //인스턴스의 참조를 꺼낼 수 있는 방법은 getInstance 함수밖에 없다.
    private SingletonService(){

    }

    //private 생성자를 쓰면 외부에서 선언할 수 없게 막는다.
    public void logic(){
        System.out.println("싱글톤 객체 로직 호출");
    }
}

생성자를 private으로 선언해 외부에서 한 번 더 생성하지 못하도록 한다.

싱글톤 패턴을 적용한 객체 사용

@Test
    @DisplayName("싱글톤 패턴을 적용한 객체 사용")
    void singletonServiceTest(){
        SingletonService singletonService1 = SingletonService.getInstance();
        SingletonService singletonService2 = SingletonService.getInstance();

        System.out.println("singletonService1 = " + singletonService1);
        System.out.println("singletonService2 = " + singletonService2);

        assertThat(singletonService1).isEqualTo(singletonService2);
        //same(==) : 진짜 인스턴스끼리 비교하는 느낌
        //equal : equals 메서드랑 같은 느낌
    }
    //객체 하나를 공유해서 사용했기 때문에 참조값도 동일하다.

다만, 스프링은 자체적으로 싱글톤으로 생성하기 때문에 따로 스프링을 사용할 때는 번거롭게 할 필요는 없다.
따라서, 스프링 컨테이너를 싱글톤 컨테이너라고 하기도 한다.

싱글톤 코드는 기존에 가지고 있던 문제를 해결해준다. 다만 코드를 추가로 작성해야하기 때문에 아래와같은 문제점이 생긴다.
싱글톤 단점

  • 패턴을 구현하는 코드 자체가 많이 들어간다.
  • 클라이언트가 구체 클래스에 의존해 OCP 원칙을 위반할 가능성이 높다.
  • 테스트하기 어렵다.
  • private 생성자로 자식 클래스를 만들기 어렵다.
  • 결론적으로 유연성이 떨어진다.
  • 안티패턴으로 불리기도 한다.
profile
혼자 성장하는 것보다 함께 성장하는 것을 선호합니다.

0개의 댓글