SpringContainer Singleton

jooog·2022년 5월 5일
0

스프링

목록 보기
23/26
post-thumbnail

📌 순수 자바 코드로 싱글톤 객체 생성

스프링 없이 순수 자바코드로 싱글톤 객체 만들어보기

SingletonService

//싱글톤 객체 만들기
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

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으로 만들어서 외부에서 객체를 생성할 수 없도록 막아주는 코드를 작성해야 한다. 이런식으로 매번 작성하면 비효율적이다.

싱글톤 패턴의 문제점

  • 작성해야 하는 코드의 양이 상당히 많아진다.
  • 클라이언트가 구체 클래스에 의존해서 DIP 원칙을 위반하게 된다.
  • 테스트가 어려우며 내부 속성을 변경해야하거나 초기화해야 할 때 어려움을 겪을 수 있다.
  • 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);

    }

스프링 컨테이너를 생성해서 객체를 조회해보면 하나의 동일한 객체가 출력되는 것을 확인할 수 있다.

동일한 객체를 반복해서 생성하는 것이 아니라 한번 생성된 객체를 공유하는 것을 확인할 수 있다.

이 글은 김영한님의 스프링 핵심 원리 강의를 듣고 정리한 내용입니다.

0개의 댓글