소프트웨어 디자인 패턴에서 싱글톤(Singleton) 패턴은 생성자가 여러 차례 호출되더라도 실제로 생성되는 객체는 하나이고 최초 생성 이후에 호출된 생성자는 최초의 생성자가 생성한 객체를 재사용하는 형태를 말합니다. Show 프로그램 내에서 객체가 단 하나만 존재하는 것이 보장되야 하거나, 객체의 크기가 커서 여러 번 재사용해야 하는 경우에 주로 사용됩니다. 싱글톤 패턴의 구현 방법으로는 크게 2가지가 있습니다. static과 synchronized 이용
또한, 참고: Java volatile이란? LazyHolder 이용
프로그램이 실행된 직후에는 하지만, 효율적이며 싱글톤 패턴 구현 시 추천되는 방법입니다. 스프링 컨테이너에서 생성되어 관리되는 핵심 객체를 스프링 빈(Bean)이라고 합니다. 빈을 등록할 때, 아무런 설정을 하지 않으면 기본적으로 싱글톤 스코프(Scope)로 생성됩니다. 싱글톤 스코프는 프로그램에서 해당 빈의 인스턴스를 오직 하나만 생성해서 재사용하는 것을 말합니다.
싱글턴 스코프는 상태를 저장하지 않고 로직만 존재하는 경우에 선택하는 것이 좋습니다. 로직만을 처리할 경우 매번 객체를 생성해줄 필요 없이 이전 객체를 재사용하는 것이 효율적이기 때문입니다. 참고: Spring Bean Scope 종류 웹 애플리케이션과 싱글톤
싱글톤 패턴
코드 (main이 아닌 test영역에 위치)
싱글톤 패턴을 적용하면 고객의 요청이 올 때마다 객체를 생성하는 것이 아니라, 이미 만들어진 객체를 공유해서 효율적으로 사용할 수 있다. 하지만 싱글톤 패턴은 다음과 같이 여러가지 문제점들을 가진다. 문제점
<참고자료> 싱글톤 컨테이너
싱글톤 컨테이너 적용 후
싱글톤 방식의 주의점
전역에서 공유된다는 것, 메모리 영역에서 프로세스 전체에서 공유된다는 것. (생성된 인스턴스는 JVM 메모리의 힙영역에 할당되니까!) 공유변수의 동시성 문제는 OS에서도 나오는 중요한 개념! 아니면 아예 상태를 유지하지
않도록 설계해라! 공유하는 값이 없도록!
상태를 유지할 경우 발생하는 문제점 예시
@Configuration과 싱글톤
AppConfig코드를 보자
@Configuration과 바이트 코드 조작의 마법스프링 컨테이너는 싱글톤 레지스트리이다. 따라서 스프링 빈이 싱글톤이 되도록 보장해주어야한다. 그런데 스프링이 자바 코드까지 어떻게 할 수는 없다. 위의 자바 코드를 보면 분명 3번 호출이 되어야하는데, 한 번만 호출되고있다. 코드
만약 순수한 자바 클래스라면 아래와 같이 출력되어야한다. 그런데 예상과는 다르게 클래스 명에 xxxCGLIB가 붙으면서 복잡한 이름을 갖게된 것을 알 수 있다.
이름은 appConfig 이름을 가져가고, 실제 등록되는 스프링 빈은 @CGLIB 클래스의 인스턴스가 등록된다. 스프링이 CGLIB 바이트코드 조작 라이브러리를 사용하여 만든 클래스가 바로 스프링 빈이 싱글톤이 보장되도록 해준다. 아마도 다음과 같이 바이트 코드를 조작해서 작성되어있을 것이다. (실제로는 CGLIB의 내부 기술을 사용하는데 매우 복잡하다.) AppConfig@CGLIB 예상 코드
@Configuration을 적용하지 않고, @Bean만 적용한다면?
무슨 문제가 있을까? 스프링 빈 등록시 아까와 다르게 memberRepository가 3번 호출된다!! memberService와 orderService에 주입되는 memberRepository 객체는 스프링에 등록된 빈 객체가 아닌, 메서드 호출로 새로 생성된 인스턴스가 주입된다.😫 (스프링 컨테이너가 관리하지 않는 객체다) 정리
해당 게시글은 인프런 김영한님의 <스프링 핵심 원리 - 기본편>을 듣고 정리한 내용입니다. |