일반적으로 Spring-Boot 쓰다보면 싱글톤 관리할려고 할 때 @Bean, @Component, 등등 어노테이션으로 객체를 관리한다. 그러다가 문득 아예 로우레벨에서 싱글톤으로 관리하는 방법도 알면 좋을 것 같아서 정리해본다.
- Holder 패턴
class MySingleton(
private val name: String
) {
companion object {
private val INSTANCE: MySingleton = Holder.INSTANCE
fun getInstance(): MySingleton {
return INSTANCE
}
//
private class Holder {
companion object {
val INSTANCE: MySingleton = load()
fun load(): MySingleton {
return MySingleton(
name = "MySingleton"
)
}
}
}
}
}
이렇게 해놓고 MySingleton.getInstance() 로 가져다 쓰면 된다. 일단 val 로 인스턴스 교체 안되도록 막아놨고 static 으로 init 될 때 바로 초기화 된다.
java 로 하면 아래처럼 할 수 있다.
public class MySingleton {
private String name;
private MySingleton(String name) {
this.name = name;
}
private static class Holder {
private static final MySingleton INSTANCE = load();
private static MySingleton load() {
return new MySingleton("MySingleton");
}
}
public static MySingleton getInstance() {
return Holder.INSTANCE;
}
}
Spring 에서 제공하는 DI 필요없다고 한다면 이런식으로 싱글톤 관리하는 방법도 있다는 정도로 알아두면 좋을 것 같다. 이 방식은 Sring boot 안쓰는 레거시 코드에서 활용하면 좋을 듯.