본문 바로가기

Backend/Java

자바 싱글톤 패턴 (Java Singleton Pattern)

자바 환경에서 싱글톤으로 객체를 사용하는 방법에 대해서 알아볼게요.

싱글톤 패턴은 디자인 패턴 중 하나로 최초 한 번만 객체를 생성을 하여 메모리에 할당하는 기법이에요.

 

동일한 객체를 지속적으로 사용해야 할 때가 있어요.

이 때마다 인스턴스를 생성해내는 것보다 하나의 인스턴스를 사용하는 것이 리소스 절약면에서 유리합니다.

 

싱글톤을 구현하는 방법은 굉장히 많이 나와있지만 딱 두 가지만 알면 되요.

  • 기본 방법
  • 많이 쓰는 방법

Simple 방법

우선, 가장 기본 방법부터 작성해볼게요.

최초 한 번 객체를 초기화하기 때문에 Thread-Safe를 보장합니다.

하지만, 객체를 사용하지도 않는 경우에도 이미 생성되어 있어서 사용하지 않는다면 리소스 낭비가 있을 수 있습니다.

사실 사용하지 않을 객체를 싱글톤으로 만드는 것부터가 이상한거라 잘 판단하고 적용해도 무방합니다.

 

그래도 개발자들은 이 조금의 찝찝함조차 참을 수 없었나봐요.

그래서 많은 방법들이 소개되었어요.

 

public class Singleton {

	private Singleton() {
		System.out.println("Hello singleton!!");
	}

	private static Singleton singleton = new Singleton();

	public static Singleton getInstance() {
		return singleton;
	}

}

LazyHolder 기법

순수하게 자바만 사용하는 경우 가장 인기있는 방법이에요. (작성일자 기준)

getInstance() 메서드를 호출할 때 LazyHolder 클래스를 로딩하고 Singleton 객체를 초기화합니다.

또한, 클래스를 로딩하는 시점에는 Thread-Safe를 보장되어 인스턴스가 여러 개 생길 수 없어요.

 

public class Singleton {

	private Singleton() {
		System.out.println("Hello singleton!!");
	}

	private static class LazyHolder {
		public static final Singleton INSTANCE = new Singleton();
	}

	public static Singleton getInstance() {
		return LazyHolder.INSTANCE;
	}

}

 


싱글톤 패턴으로 클래스를 구현했다면 해당 클래스는 new Singleton 으로 객체를 생성할 수 없어요.

getInstance 메서드를 이용해서 사용하면 됩니다.

 

public static void main(String[] args) {
	Singleton singleton = Singleton.getInstance();
}

 

제대로 적용되었는지 테스트를 해볼게요.

Singleton 생성자 안에 Hello 로그를 찍어놨죠.

싱글톤으로 제대로 구현하였다면 아래 코드를 실행해도 로그가 한 번만 찍힐거에요.

 

 

 

여기까지가 Java에서 싱글톤 패턴으로 객체를 사용하는 방법이구요.

Spring 환경이라면 달라요.

아래에 추가로 아주 간단히 설명할게요.

 


Spring Bean 이용

개발 환경이 Spring이라면 static 기반의 싱글톤을 직접 구현하는 것을 지양합니다.

스프링에서는 빈(Bean) 객체를 싱글톤 범위로 생성해요.

static 싱글톤과 다른 점은 Spring Container 안에서만 사용할 수 있다 정도만 알고 있으면 됩니다.

 

@Component
public class Singleton {

}

 

혹은

 

<bean id="singleton" class="com.example.demo.Singleton"/>

 

사용할 때는