반응형
싱글톤 패턴
싱글톤 패턴이란?
클래스의 인스턴스가 딱 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 타입으로 조회할 수 있다.
이 글은 김영한님의 "스프링 핵심 원리 - 기본편" 강의를 듣고 정리한 내용입니다.
반응형