본문 바로가기
카테고리 없음

일반 싱글톤과 스프링 싱글톤

by ernest45 2023. 7. 31.

일반 싱글톤 패턴

일반싱글톤

 

 

 

 

스프링에서 관리하는 싱글톤

 

 

 

 

bean 등록과 component의 차이 (클래스 단위 컴포넌트고 자동 등록 컴피규레이션이 필요없다)

빈은 컨피규레이션도 적어줘야하고 메서드 단위(직접 수동등록)

omponent는  클래스 단위 컴포넌트고 자동 등록 컴피규레이션이 필요없다)

 

 

싱글톤 패턴의 주의점

 

무상태성 (여러 객체가 같이 사용하기 떄문ㅇ

 

 

안녕하세요, 인프런 AI 인턴입니다.

980513k님, static 메소드에 @Bean을 사용하는 경우 싱글톤 보장을 받지 못하는 이유에 대해 설명드리겠습니다.

스프링 프레임워크에서 @Bean 어노테이션이 붙은 메소드는 해당 빈의 생성 로직을 담고 있습니다. 스프링 컨테이너는 이러한 메소드를 호출하여 빈 인스턴스를 생성하고 관리합니다.

일반적인 경우에는 스프링 컨테이너가 @Bean 어노테이션이 붙은 메소드를 자동으로 싱글톤 범위로 관리하여, 해당 빈의 요청이 있을 때마다 이미 생성된 인스턴스를 반환해줍니다. 즉, 메소드 호출을 통한 빈의 생성과 관리가 스프링 컨테이너 내부의 라이프사이클에 따라 이루어지게 됩니다.

반면, static 메소드는 클래스의 인스턴스가 생성되지 않아도 호출할 수 있는 메소드이며, 클래스 로더가 해당 클래스를 메모리에 로드할 때 메모리에 함께 배치됩니다. static 메소드는 특정 인스턴스에 속하지 않기 때문에 스프링 컨테이너가 빈을 관리하는 방식, 즉 인스턴스 레벨에서 처리하는 라이프사이클 관리, 의존성 주입 및 프록시 적용 등과 같은 과정을 거치기 어렵습니다.

그 결과, @Bean 어노테이션을 사용한 static 메소드는 스프링 컨테이너가 반환하는 빈 인스턴스에 대한 싱글톤 보장이 어려워지고, 스프링 컨테이너가 제공하는 기능들을 온전히 사용하지 못하게 됩니다. 따라서, 일반적으로 @Bean 메소드는 non-static 메소드로 선언하여 스프링 컨테이너가 제어할 수 있게 하는 것이 좋습니다.

강의 내용 중 비슷한 문제가 발생할 경우 자주하는 질문을 확인하거나, 질문 잘하기 메뉴얼을 참고해보시기 바랍니다. 추가적인 정보가 필요하다면, 강의 지식공유자님께 직접 질문해보시는 것도 좋은 방법일 것입니다.

강의 관련하여 다른 궁금한 부분이 있다면 언제든 질문해주세요. 공부하는데 도움이 되시길 바랍니다!

 

 

싱글톤을 어떻게든 보장해주는 스프링 컨테이너

 

비밀은

@Configuration에 있다.

 

 

 

 

결과로 get.Class해주니 v2까지만 나와야하는데 $$부터 뒤에까지?

 

 

 

 

 

 

즉 내가 등록한 것 처럼 보이지만 그게 아니라 스프링이 CGLIB이라는 바이트코드 조작 라이브러리가지고, 상속받아
다른 클래스를 만들고 스프링이 내가 등록한 게 아니고, 조작한 클래스를 스프링 빈으로 등록해버림

 

그 임의의 다른 클래스가 바로 싱글톤이 되도록 보장을 해준다!

 

 

조작한 클래스는 이런 식으로 구성되어 있을 것인데,

 

아까의 예를 연장해서 들어보자면,

 

memberService가 memberRepository를 호출하고 생성하고, orderService도 memberRepository를 생성할 때

위의 코드 로직으로 이미 있다면 찾아서 반환해주고, 아니라면 만드는 형식이라서 로그가 여러번 찍히지 않았던 것!

 

즉 appConfig의 memberRepository 호출 시 CGLIB의 오버라이드된 memberRepository를 호출하는 거다

 

 

 

참고로

AppConfigV2$$CGLIB은 AppConfigV2의 자식 타입이라 조회가 가능했던 것
(예전에 한 말 : 부모타입으로 조회하면 자식타입이 다 끌려 나온다!)

 

 

그렇다면

 

 

안붙여도 스프링 컨테이너에 스프링 빈으로 등록은 된다.

 

but 문제점은 CGLI의 기술을 안씀

 

 

 

 

AppConfigV2에서

 

@Configuration을 뺐을 때의 예인데 보다시피 객체를 여러 개 생성한다.!  싱글톤이 깨져버림

그리고 클래스의 인스턴스가 아니라 순수한 내 AppConfigV2를 쓴다.

 

그리고 인스턴스를 직접 찍어 봤을 때 다른 객체인 걸 확인할 수 있다.

그리고 memberService의 memberRepository는 자바코드대로 내가 직접 new한 객체가 되고, (orderService도 마찬가지)

스프링 bean이 관리하지 않는다!