싱글톤 패턴
- 클래스의 인스턴스가 오직 1개만 생성되는 것을 보장하는 디자인 패턴
- private 생성자를 통해 외부에서 임의로 new 키워드를 통해 객체 인스턴스를 사용하지 못하도록 방지
- getInstance() 메서드를 통해서만 조회 가능하게 함으로써 항상 같은 인스턴스를 반환
싱글톤 패턴 코드
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class SingletonExample { | |
private static final SingletonExample instance = new SingletonExample(); | |
public static SingletonExample getInstance() { | |
return instance; | |
} | |
private SingletonExample() {} | |
} |
* 보다 많은 코드 예시: https://betterprogramming.pub/what-is-a-singleton-2dc38ca08e92
싱글톤 패턴 장점
- TPS (Traffic Per Second)가 높은 웹 애플리케이션에서 고객 요청마다 새로운 인스턴스를 생성할 경우 메모리 낭비가 심각 -> 싱글톤 패턴을 적용할 경우 해당 문제 해결 가능
- 스프링 프레임워크 내에서는 스프링 컨테이너를 통해 고객의 요청이 들어올 때마다 객체를 생성하는 것이 아니라, 이미 생성된 객체를 공유 -> 메모리를 효율적으로 사용 가능
싱글톤 패턴 단점
- 싱글톤 패턴을 적용할 클래스를 직접 구현해야 함 (상단 코드 예시처럼)
- 클라이언트가 구체 클래스에 의존하여 SOLID 원칙 중 DIP와 OCP 원칙을 위반할 가능성이 높음
- 내부 속성을 변경하거나 초기화하기 어려움
- 테스트하기 어려움
- private 생성자로 자식 클래스를 생성하기 어려움
- 유연성이 떨어짐
스프링 컨테이너
- 상단에 언급한 싱글톤 패턴의 단점을 해결하면서, 객체 인스턴스를 싱글톤으로 관리해주는 컨테이너
- 스프링 컨테이너는 CGLIB라는 바이트코드 조작 라이브러리를 사용하여 싱글톤 컨테이너 역할을 함. 이렇게 싱글톤 객체를 생성하고 관리하는 기능을 싱글톤 레지스트리라고 함
- @Configuration 어노테이션을 적용해야지 CGLIB 라이브러리 적용 가능
- CGLIB 바이트코드 조작 라이브러리를 통해 싱글톤 패턴을 위한 별도 코드를 작성하지 않아도 됨
- DIP, OCP, 테스트, private 생성자로부터 자유롭게 싱글톤 패턴 적용 가능
* CGLIB에 대한 보다 자세한 내용: http://www.javabyexamples.com/cglib-proxying-in-spring-configuration
싱글톤 패턴 적용 시 주의할 점
- 스프링 컨테이너가 싱글톤 패턴의 단점을 보완해준다고 해도 주의해야 할 점이 몇 개 있음
- 싱글톤 패턴을 적용할 경우 하나의 객체 인스턴스를 공유하기 때문에 stateful 하기 설계하면 안 됨 즉, stateless (무상태)로 설계해야 함
- 특정 클라이언트에 의존적인 필드가 있으면 안 됨
- 특정 클라이언트가 값을 변경할 수 있는 필드가 있으면 안 됨
- 상태를 변경하지 않는 조회 기능만 있는 것을 추천
- 필드 대신 자바에서 공유되지 않는 지역변수, 파라미터, ThreadLocal 등을 사용해야 함
- 스프링 빈 내 필드에 공유 값을 설정할 경우 장애 발생 시 디버깅하기 힘들고 큰 문제 야기할 가능성이 있음
참고
인프런 스프링 핵심 원리 - 기본편 (김영한 강사님)
반응형
'면접 준비' 카테고리의 다른 글
서블릿 (Servlet) 간단 정리 (0) | 2021.05.28 |
---|---|
웹 서버 vs WAS 비교 (0) | 2021.05.28 |
객체지향 설계 원칙: SOLID 법칙 (0) | 2021.05.15 |
[Java] 정렬 (0) | 2021.04.25 |
ios_base::sync_with_stdio(false); cin.tie(null); 구문을 추가해주는 이유 (11) | 2020.11.03 |