포스트

09. 싱글톤 컨테이너

09. 싱글톤 컨테이너

싱글톤 컨테이너

  • 스프링은 일반적으로 웹 용 컨테이너

  • 일반적으로 전부 웹 어플리케이션
  • 일반적으로 웹은 다수의 사용자가 사용함
    • A, B, C가 동시에 요청을 하면?
    • DI는 어떤식으로?
    • 기존의 AppConfig 는 지속적으로 객체를 생성한다.
    • 트래픽이 초당 100이라면? → 100개의 객체를 생성 → 시스템 부하
  • 하나의 인스턴스만 생성해서 계속 사용한다면?

싱글톤 패턴

  • 클래스의 인스턴스가 딱 1개만 생성되는 것을 보장하는 디자인 패턴
  • 생성자의 private 로 한다.
  • static 영역에 자기 자신을 객체로 만들어 저장한다.
    • 필요로 할때마다 getInstance() 를 사용해 객체를 가져온다.

싱글톤 패턴의 문제점

  • 구현 코드 복잡
  • 의존 관계상 클라이언트가 구제 클래스에 의존 → DIP 위반
  • 테스트 어려움
  • 클라이언트가 구체 클래스에 의존 → OCP 위반 가능성 높음
  • 상속 불가
  • 유연성 감소

싱글톤 컨테이너

Spring은 싱글톤 패턴의 문제점은 해결하고 객체 인스턴스를 싱글톤으로 관리한다.

  • Bean은 대표적인 싱글톤
    • 컨테이너는 하나의 객체만 생성
  • 싱글톤의 단점을 해결하고 장점만 살릴 수 있다.
    • 싱글톤 패턴을 위한 지저분한 생성자 코드의 생략
    • DIP와 OCP에서 안전하게 자유롭게 싱글톤 사용 가능

싱글톤 방식의 주의점

  • 싱글톤을 어떤식으로 만들던, 객체 인스턴스가 공유되기에 싱글톤 객체는 상태를 유지하게 설계되면 안된다.
  • 무상태(stateless)로 해야한다.
    • 특정 클라이언트에 의존되서는 안된다.
    • 특정 클라이언트가 값을 변경 할 수 있는 필드가 있으면 안된다!
    • Read 기능만 사용하는게 좋다.
    • 필드 대신에 자바에서 공유되지 않는 지역변수, 파라미터, ThreadLocal 등을 지향
    • 만약 공유 변수가 있다면 큰일날 수도?
    • 일반적인 스레드에서 일어나는 문제를 보게된다…

@Configuration과 싱글톤

  • 우리가 만든 AppConfig 는 과연 싱글톤을 꺠지는 코드일까?

테스트

  • 둘이 같은 객체로 생성된다. 모두 같은 Bean이다!
  • Java 코드인데 어떻게 이런…?

@Configuraion과 바이트 코드 조막의 마법

  • 스프링 컨테이너는 싱글톤 레지스트리이다. → 싱글톤의 보장

    스크린샷 2024-04-25 오후 8.23.18.png

  • @Configuraion 을 붙인 클래스는 아래와 같이 보인다.

    스크린샷 2024-04-25 오후 8.24.43.png

    • 내가 만든 AppConfig는 본래 class hello.core.AppConfig 로 등록되어야한다.
    • 근데 뒤에 이상한게 붙는다.
  • 스프링은 내가 만든 AppConfig를 상속 받은 임의의 클래스를 추가로 만들어 그걸 빈으로 등록했다!

스크린샷 2024-04-25 오후 8.26.57.png

  • CGLIB를 사용해 실제 컨테이너에는 내가 등록한 객체가 아닌 다른 객체가 들어가 있다.
  • 이를 통해 @Bean이 붙은 메서드나 객체의 중복된 객체 생성을 체크해 로직을 통해 중복 생성을 방어하고 bean을 싱글톤 상태로 유지시킨다.
  • 물론 자식 타입으로 저장 되기에 AppConfig으로 조회시에도 조회가 된다!
  • AOP도 이러한 비슷한 로직을 실행한다.

그렇다면… @Configuration 없이 @Bean만 적용한다면?

  • 싱글톤이 꺠진다.
  • 즉 Bean 등록은 되지만 싱글톤을 보장하지는 않는다.
  • 항상 @Configuration을 사용하도록 하자…
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.

© 김규형. 일부 권리 보유

Powered by Jekyll with Chirpy theme