[Spring] 싱글톤 컨테이너

ggamang·2023년 3월 29일
0

JAVA&Spring

목록 보기
15/27

웹애플리케이션과 싱글톤

대부분의 스프링 애플리케이션은 웹 애플리케이션이다

웹 애플리케이션 - 여러 고객이 동시에 요청을 한다

우리가 만든 스프링 없는 순수한 DI 컨테이너인 AppConfig는 요청 시 마다 객체를 새로 생성한다(메모리 낭비)

싱글톤 패턴 : 객체가 1개만 생성되고 공유하도록 설계

싱글톤 패턴

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

생성자를 private으로 선언해서 외부에서 new 키워드를 사용한 객체 생성을 못하게 막는다

→ 호출 시 마다 같은 객체 인스턴스를 반환한다

싱글톤 패턴의 문제점

  • 싱글톤 패턴 구현하는 코드 자체가 많이 들어간다
  • DIP위반: 의존관계 상 클라이언트가 구체 클래스에 의존한다
  • OCP위반 가능성이 높다
  • 유연성이 떨어진다 - 내부속성 변경 어려움, 자식 클래스 생성 어려움

싱글톤 컨테이너

스프링 컨테이너는 싱글톤 패턴의 문제점을 해결하면서, 객체 인스턴스를 싱글톤으로 관리한다

  • 싱글톤패턴을 위한 지저분한 코드 불필요
  • DIP, OCP, 테스트, private 생성자로부터 자유롭게 싱글톤 사용 가능

싱글톤 방식의 주의점

여러 클라이언트가 하나의 같은 객체 인스턴스를 공유하기 때문에 Stateless로 설계해야 한다

  • 특정 클라이언트에 의존적인 필드 없어야 함
  • 특정 클라이언트가 값을 변경할 수 있는 필드가 있으면 안 됨
  • 가급적 읽기만 가능해야 한다
  • 필드 대신에 자바에서 공유되지 않는, 지역변수, 파라미터, ThreadLocal 등을 사용해야 한다.

price 필드는 공유되는 필드인데, 특정 클라이언트가 값을 변경하고 있다.

무상태로 설계하는 방법

→ 지역변수로 해결한다

@Configuration과 싱글톤

  1. memberService에서 new MemoryMemberRepository() 호출
  2. orderService에서 new MemoryMemberRepository() 호출

⇒ 각각 다른 2개의 MemoryMemberRepository가 생성되면서 싱글톤이 깨지는 것처럼 보이나, 싱글톤 유지

  • memberRepository()를 총 한 번만 호출하고 있다

@Congifuration과 바이트코드 조작의 마법

스프링은 클래스의 바이트코드를 조작하는 라이브러리를 사용

내가 만든 클래스가 아니라 스프링이 CGLIB라는 바이트코드 조작 라이브러리를 사용해서 AppConfig를 상속받은 임의의 다른 클래스를 만들고, 그 다른 클래스를 스프링 빈으로 등록한 것이다

  • 그 임의의 클래스가 싱글톤을 보장시켜 주는 것이다

스프링의 설정 정보는 항상 @Configuration을 사용하면 된다

@Bean만 사용해도 스프링 빈으로 등록은 되지만, 싱글톤이 보장이 되지는 않는다

0개의 댓글