반응형
이번 포스트에서는 스프링의 Singleton 패턴에 대해서 알아보자
1. Singleton 패턴의 개념
Singleton 패턴은 객체지향 프로그래밍에서 자주 사용되는 디자인 패턴이다. 이 패턴의 핵심은 클래스의 인스턴스를 딱 하나만 만들어서, 어플리케이션 전체에서 공유한다는 것이다. 이렇게 하면 메모리 사용을 줄일 수 있고, 데이터 공유가 편리해진다.
예를 들어, 어떤 클래스가 데이터베이스 연결이나 시스템 설정 같은 전역적으로 사용되는 자원을 다룬다고 생각해보자. 이런 자원은 한 번만 만들어서 계속 사용하는 게 효율적이다. Singleton 패턴을 쓰면, 이 클래스의 인스턴스를 한 번만 만들고, 어디서든 이 인스턴스를 불러와서 사용할 수 있다.
스프링 프레임워크에서는 이 Singleton 패턴을 기본적으로 사용한다. 스프링 컨테이너가 클래스의 인스턴스를 만들 때, 기본적으로는 Singleton으로 관리되기 때문에, 스프링이 관리하는 빈(Bean)은 대부분 Singleton 인스턴스이다.
이런 방식은 메모리를 효율적으로 사용할 수 있게 해주고, 어플리케이션 전반에서 일관된 상태를 유지할 수 있도록 도와준다. 하지만, Singleton 패턴을 사용할 때는 상태 관리에 주의해야 한다. 여러 곳에서 공유되는 인스턴스이기 때문에, 상태가 예기치 않게 변경될 위험이 있다.
2. Singleton 패턴은 주로 다음과 같은 상황에 활용된다.
2-1. 전역 리소스 접근
- 어플리케이션 전체에서 공유되어야 하는 리소스, 예를 들어 데이터베이스 연결이나 시스템 설정 같은 것들에 접근할 때 Singleton 패턴이 유용하다. 전역적으로 하나의 인스턴스를 사용하기 때문에, 리소스 관리가 훨씬 수월해 진다.
2-2. 중요 데이터 관리
- 설정 정보나 로그 기록 같은 중요한 데이터를 다룰 때도 Singleton 패턴이 적합하다. 왜냐하면 이 데이터들은 어플리케이션의 여러 부분에서 일관되게 사용되어야 하기 때문이다.
2-3. 비용이 큰 작업 수행
- 메모리 사용이 크거나 계산 비용이 많이 드는 작업을 할 때 Singleton 패턴을 사용하면, 이러한 자원을 효율적으로 사용할 수 있다. 한 번만 인스턴스를 생성하고 재사용하기 때문이다.
3. Singleton 패턴의 구현 방법
Singleton 패턴을 구현하는 방법은 여러 가지가 있지만, 일반적으로 다음과 같은 특징을 갖는다.
3-1. 프라이빗 생성자
- 클래스의 생성자를 private으로 선언해서 외부에서 이 클래스의 인스턴스를 직접 만들 수 없게 하면 클래스 내부에서만 인스턴스를 생성할 수 있게 된다.
3-2. 정적 메서드로 인스턴스 반환
- 클래스 안에 유일한 인스턴스를 저장할 정적 필드를 만들고, 이 인스턴스를 반환하는 정적 메서드를 제공한다. 이 메서드를 통해서만 인스턴스에 접근할 수 있다.
3-3. 지연 초기화
- 인스턴스가 필요할 때까지 생성하지 않고, 필요한 시점에 생성한다. 이렇게 하면 리소스를 절약할 수 있다.
3-4. 스레드 안전성
- 다중 스레드 환경에서도 문제 없이 작동하도록 구현해야 한다. 여러 스레드가 동시에 인스턴스에 접근해도 문제가 발생하지 않도록 신경 써야 한다.
4. 자바의 Singleton 패턴 예시코드
public class Singleton {
private static Singleton instance;
private Singleton() {
// private 생성자
}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
- 이 코드는 자바에서 Singleton 패턴을 구현하는 방법을 보여줘. Singleton 클래스는 instance라는 이름의 정적 필드를 가지고 있고, getInstance() 메서드를 통해 이 인스턴스를 반환해. private Singleton()은 클래스 외부에서 인스턴스를 생성하는 것을 방지하기 위해 생성자를 private으로 설정한 거야.
- public static synchronized Singleton getInstance()는 스레드 안전성을 고려한 인스턴스 생성 방법이야. 여러 스레드가 동시에 접근해도 문제가 없도록 synchronized 키워드를 사용했지. 이렇게 지연 로딩 방식을 사용해서 필요할 때 인스턴스를 생성하는 거야.
5. Spring과 Singleton의 관계
Spring Framework에서 빈(Bean)을 관리하는 기본적인 방식은 Singleton 패턴과 관련이 있다. Spring은 기본적으로 빈을 Singleton으로 관리하며, 한 개의 인스턴스를 생성하고 모든 요청에 대해 동일한 인스턴스를 반환한다.
스프링 프레임워크에서는 빈(Bean)을 관리할 때 주로 Singleton 패턴을 사용하는데 이유는 다음과 같다.
5-1. 성능 및 자원 관리
- 빈이 Singleton으로 관리되면 메모리와 자원을 효율적으로 사용할 수 있다. 매번 새로운 인스턴스를 만드는 비용을 줄이고, 중요한 리소스를 공유할 수 있기 때문이다.
5-2. 일관성과 데이터 공유
- 같은 인스턴스가 여러 컴포넌트에 공유되니, 데이터의 일관성을 유지하기 쉽다. 설정 정보나 데이터베이스 연결 같은 중요한 자원을 효과적으로 관리할 수 있다.
5-3. 의존성 주입의 편의
- Singleton 빈은 의존성 주입을 통해 다른 컴포넌트에 쉽게 주입될 수 있다. 모든 컴포넌트가 동일한 인스턴스를 사용하면 의존성 관리가 수월해진다.
스프링에서는 개발자가 직접 싱글톤을 구현하거나 인스턴스를 관리할 필요가 없다. 스프링 컨테이너가 이 모든 걸 해주기 때문이다. 그리고 Singleton만 있는 게 아니라, Prototype, Request, Session 같은 다른 스코프도 지원해서 더 다양한 요구사항에 맞게 인스턴스를 관리할 수 있다.
스프링의 다형성, OOP가 궁금하다면?
반응형
'Spring 기초 > Spring 기초 지식' 카테고리의 다른 글
Spring Framework 이해하기: 다형성, 개방-폐쇄 원칙(OCP), 인터페이스 활용의 장점 (0) | 2023.08.08 |
---|---|
@ControllerAdvice, @RestControllerAdvice - 중앙집중 예외처리 (0) | 2023.08.07 |
스프링 프레임워크의 핵심: 제어의 역전(IoC) (0) | 2023.08.07 |
[스프링, 스프링부트] Spring - 의존성 주입(DI - Dependency Injection) (0) | 2023.08.07 |
[스프링, 스프링부트] Spring Container (스프링 컨테이너) (0) | 2023.08.07 |