🥎 싱클턴(singleton)이란?
- 인스턴스를 오직 하나만 생성할 수 있는 클래스를 말함
- 예시
- 함수와 같은 무상태 객체
- 설계상 유일해야 하는 시스템 컴포넌트
- 클래스를 싱글턴으로 만들면 이를 사용하는 클라이언트를 테스트하기가 어려워질 수 있음
🤔 싱클턴 패턴을 왜 사용할까?
- 인스턴스를 오직 하나만 생성하므로서 객체를 여러번 생성할 필요가 없고 객체를 공유할 수 있음
- 스프링에서 관리하는 bean도 싱글턴 패턴으로 만들어져 의존성을 주입할 때 동일한 객체를 사용함
- **DBCP(Database Connection Pool)**의 경우에도 DB와 애플리케이션을 연결하기 위해 매번 객체를 생성하여 관리하는 것보다 최초의 생성된 객체를 재사용하면서 connection을 관리하는게 더 효율적
🧚🏻 싱글턴을 만드는 방식
1. public static final 필드 방식
public class Elvis {
public static final Elvis INSTANCE = new Elvis();
private Elvis() { ... }
public void leaveTheBuilding() { ... }
}
-
장점
- 해당 클래스가 싱글턴임이 API에 명확히 드러난다는 것
- 간결함
-
단점
- 권한이 있는 클라이언트는 리플렉션 API인 AccessibleObject.setAccessible을 사용해 private 생성자를 호출할 수 있음
- 리플렉션이란?
- 구체적인 클래스 타입을 알지 못해도 컴파일된 바이트 코드를 통해 해당 클래스의 메소드, 타입, 변수까지 접근가능한 자바 API
- 컴파일된 바이트 코드에 접근이 가능하기 때문에 static영역에도 접근 가능하고 private로 선언된 부분까지 접근할 수 있음
- 이 공격을 방어하려면?
- 생성자를 수정하여 두 번째 객체가 생성되려할 때 예외를 던지게 하면 됨
2. 정적 팩터리 방식
public class Elvis {
private static final Elvis INSTANCE = new Elvis();
private Elvis() { ... }
public static Elvis getInstance() { return INSTANCE; }
public void leaveTheBuilding() { ... }
}