Peony의 기록 창고 🌼
article thumbnail
반응형

싱글톤 패턴

싱글톤 패턴이란?

클래스의 인스턴스가 딱 1개만 생성되는 것을 보장하는 디자인 패턴

싱글톤 패턴을 적용하면 고객의 요청이 올 때 마다 객체를 생성하는 것이 아니라, 이미 만들어진 객체를 공유해서 효율적으로 사용할 수 있다. 하지만 싱글톤 패턴은 다음과 같은 수 많은 문제점들을 가지고 있다.

 

싱글톤 패턴 문제점

  • 싱글톤 패턴을 구현하는 코드 자체가 많이 들어간다.
  • 의존관계상 클라이언트가 구체 클래스에 의존한다. → DIP를 위반
    • 자연스럽게 OCP 원칙을 위반할 가능성이 높다.
  • 테스트하기 어렵다.
  • 내부 속성을 변경하거나 초기화 하기 어렵다.
  • private 생성자로 자식 클래스를 만들기 어렵다.
  • 결론적으로 유연성이 떨어진다.
  • 안티패턴으로 불리기도 한다.

 

싱글톤 컨테이너

  • 스프링 컨테이너는 싱글톤 패턴의 문제점을 해결하면서, 객체 인스턴스를 싱글톤으로 관리해준다.
    • 스프링 컨테이너 덕분에 고객의 요청이 올 때마다 객체를 생성하는 것이 아닌, 이미 만들어진 객체를 공유해서 재사용할 수 있다.
  • @Configuration 애노테이션을 사용하는 설정 클래스에서 등록되는 스프링 빈들은 모두 스프링 컨테이너에 의해 싱글톤으로 관리가 된다.
    • 클래스 내부에 동일한 객체를 생성하는 코드가 중복 호출되더라도 하나의 인스턴스로 관리되어 싱글톤이 유지된다.

 

싱글톤 방식의 주의점

  • 싱글톤 객체는 상태를 유지하게 설계하면 X → 무상태 O
    • 특정 클라이언트에 의존적인 필드 X
    • 특정 클라이언트가 값을 변경할 수 있는 필드 X

 

@Configuration과 싱글톤

@Configuration
public class AppConfig {
    @Bean
    public MemberService memberService() {
        return new MemberServiceImpl(memberRepository());
    }

    @Bean
    public OrderService orderService() {
        return new OrderServiceImpl(
                memberRepository(),
                discountPolicy());
    }

    @Bean
    public MemberRepository memberRepository() {
        return new MemoryMemberRepository();
    }
      ... 
}

AppConfig에 memberService와 orderService 빈을 만드는 코드를 보자. 두 메서드에서 동일하게 new MemoryMemberRepository()를 호출하는 것을 볼 수 있다. 이렇게 보면 싱글톤이 깨지는 것 처럼 보이는데 스프링 컨테이너는 이 문제를 어떻게 해결할까?

 

CGLIB를 이용한 싱글톤 컨테이너 관리

CGLIB이란?
코드 생성 라이브러리(Code Generator Library)로 런타임시에 동적으로 자바 클래스의 프록시를 만들어주는 기능을 제공한다. 대표적으로 Hibernate에서는 자바빈 객체에 대한 프록시를 생성할 때 사용돠고, Spring에서는 스프링 컨테이너 혹은 프록시 기반 AOP를 구현할 때 주로 사용된다.

 

CGLIB는 기존 소스코드에 추가기능을 덧붙히는 기존 객체의 하위 객체인 프록시 객체를 만드는데 사용이 되는데, 이를 이용해 스프링은 싱글톤을 유지할 수 있도록 한다.

 

AppConfig@CGLIB는 AppConfig의 자식 타입으로, AppConfig 타입으로 조회할 수 있다.

 

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

 

반응형
profile

Peony의 기록 창고 🌼

@myeongju