์ฑ๊ธํค
์ฑ๊ธํค ํจํด์ ์ด๋ค ํด๋์ค์ ์ธ์คํด์ค๊ฐ ์ค์ง ํ๋๋ง ์์ฑ๋๋ ๊ฒ์ ๋ณด์ฅํ๋ฉฐ, ์ด ์ธ์คํด์ค์ ์ ๊ทผํ ์ ์๋ ์ ์ญ์ ์ธ ์ ์ด์ ์ ์ ๊ณตํ๋ ํจํด์ ๋๋ค.
์ฑ๊ธํค์ ๊ตฌํํ๋ ์ฌ๋ฌ๊ฐ์ง ๋ฐฉ๋ฒ์ด ์๋๋ฐ, ํ๋ํ๋ ์ดํด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
1. Eager Initialization (์ด๋ฅธ ์ด๊ธฐํ, Thread - safe)
Eager Initialization์ ๊ฐ์ฅ ๊ฐ๋จํ ํํ์ ์ฑ๊ธํค ๊ตฌํ ๋ฐฉ๋ฒ์ ๋๋ค.
public class Singleton {
private static final Singleton instance = new Singleton();//ํด๋์ค ๋ก๋ฉ ์์ ์ ์์ฑ
private Singleton(){} //private ์์ฑ์๋ก ์ธ๋ถ ํด๋์ค๋ก๋ถํฐ ์ธ์คํด์ค๊ฐ ์์ฑ๋๋๊ฒ์ ์ฐจ๋จํ๋ค.
public static Singleton getInstance(){
return instance;
}
}
ํด๋์ค์ ์ธ์คํด์ค๋ฅผ ํด๋์ค ๋ก๋ฉ ์์ ์ ์์ฑํ๋ ๋ฐฉ๋ฒ์ผ๋ก, Thread-safeํฉ๋๋ค.
๊ทธ๋ฌ๋ ์ ํ๋ฆฌ์ผ์ด์ ์์ ํด๋น ์ธ์คํด์ค๋ฅผ ์ฌ์ฉํ์ง ์๋๋ผ๋ ์ธ์คํด์ค๋ฅผ ์์ฑํ๊ธฐ ๋๋ฌธ์ ๋ญ๋น๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค..
์ด ๋ฐฉ๋ฒ์ ์ฑ๊ธํค ํด๋์ค๊ฐ ๋ค์ ์ ์ ๋ฆฌ์์ค๋ฅผ ๋ค๋ฃฐ ๋ ์ฌ์ฉํด์ผ ํ๋ฉฐ, File System์ด๋ Database Connection ๋ฑ ํฐ ๋ฆฌ์์ค๋ค์ ๋ค๋ฃจ๋ ์ฑ๊ธํค์ ๊ตฌํํ ๋๋ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
๊ฒ๋ค๊ฐ Exception์ ๋ํ Handling๋ ์ ๊ณตํ์ง ์์ต๋๋ค.
2. Static Block Initialization (์ ์ ๋ธ๋ญ ์ด๊ธฐํ, Thread - safe)
Static Block Initialization์ 1๋ฒ์์ ์ดํด๋ณธ Eager Initialization๊ณผ ์ ์ฌํ์ง๋ง,
static block์ ํตํด์ Exception Handling์ ๋ํ ์ต์ ์ ์ ๊ณตํฉ๋๋ค.
public class Singleton {
private static Singleton instance;
private Singleton(){}
static{
try{
instance = new Singleton();
}catch(Exception e){
throw new RuntimeException("Exception occured in creating singleton instance");
}
}
public static Singleton getInstance(){
return instance;
}
}
Exception์ ๋ํ Handling์ด ์ถ๊ฐ๋์๋ค๋ ๊ฒ ๋ง๊ณ ๋ Eager Initialization๊ณผ ๋์ผํฉ๋๋ค.
3. Lazy Initialization (์ ์ ๋ธ๋ญ ์ด๊ธฐํ)
Lazy Initialization์ ์์ ๋ ๋ฐฉ์๊ณผ๋ ๋ฌ๋ฆฌ ๋์ค์ ์ด๊ธฐํํ๋ ๋ฐฉ๋ฒ์ ๋๋ค.
์ด๋ ์ ์ญ์์ ์ ๊ทผ ๊ฐ๋ฅํ getInstance() ๋ฉ์๋๋ฅผ ํธ์ถํ ๋์ ์ธ์คํด์ค๊ฐ ์๋ค๋ฉด ์์ฑํฉ๋๋ค.
public class Singleton {
private static Singleton instance;
private Singleton(){}
public static Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
์ด ๋ฐฉ๋ฒ์ ์ฌ์ฉํ๋ค๋ฉด 1, 2๋ฒ์ด ๊ฐ์ง๊ณ ์์๋ ๋ฌธ์ ์ ์ธ '์ฌ์ฉํ์ง ์์์ ๊ฒฝ์ฐ ์ธ์คํด์ค๊ฐ ๋ญ๋น'์ ๋ํ ํด๊ฒฐ์ฑ ์ด ๋์ง๋ง, ๋ค๋ฅธ ๋ฌธ์ ์ ์ด ๋ฐ์ํฉ๋๋ค.
๋ฉํฐ์ค๋ ๋(multi-thread) ํ๊ฒฝ์์์ ๋๊ธฐํ ๋ฌธ์
๋ง์ฝ ์ธ์คํด์ค๊ฐ ์์ฑ๋์ง ์์ ์์ ์์ ์ฌ๋ฌ ์ฐ๋ ๋๊ฐ ๋์์ getInstance()๋ฅผ ํธ์ถํ๋ค๋ฉด ์์์น ๋ชปํ๊ฒ ๋ง์ ์ธ์คํด์ค๊ฐ ์์ฑ๋ ์ ์์ต๋๋ค.
4. Lazy Initialization with synchronized
(๋๊ธฐํ ๋ธ๋ญ์ ์ฌ์ฉํ ๊ฒ์ผ๋ฅธ ์ด๊ธฐํ, Thread - safe)
๋ฉํฐ ์ค๋ ๋ ํ๊ฒฝ์์์ ๋๊ธฐํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด getInstance() ๋ฉ์๋์ synchronized๋ฅผ ๊ฑธ์ด๋์ด Thread-safe๋ฅผ ๋ณด์ฅํด์ฃผ๋ ๋ฐฉ๋ฒ์ ๋๋ค.
public class Singleton {
private static Singleton instance;
private Singleton(){}
public static synchronized Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
์ด ๋ฐฉ๋ฒ์ ์ฌ์ฉํ๋ฉด 1,2๋ฒ์ด ๊ฐ์ง๊ณ ์๋ ๋ฌธ์ ์ ์ธ ์ธ์คํด์ค ๋ญ๋น์, 3๋ฒ์ด ๊ฐ์ง๊ณ ์๋ Thread-safeํ์ง ์๋ค๋ ๋จ์ ์ ๋ชจ๋ ํด๊ฒฐํ ์ ์์ต๋๋ค.
๊ทธ๋ฌ๋ synchronized ํค์๋ ์์ฒด์ ๋ํ ๋น์ฉ์ด ํฌ๊ธฐ ๋๋ฌธ์ ์ฑ๊ธํค ์ธ์คํด์ค ํธ์ถ์ด ์ฆ์ ์ดํ๋ฆฌ์ผ์ด์ ์์๋ ์ฑ๋ฅ์ด ๋จ์ด์ง๊ฒ ๋ฉ๋๋ค.
5. Lazy Initialization, Double Checking Locking (DCL, Thread - safe)
์ธ์คํด์ค๊ฐ ์์ฑ๋์ด ์์ง ์์ ์์ ์๋ง synchronized๊ฐ ์คํ๋๊ฒ๋ ๊ตฌํํ๋ ๋ฐฉ์์ ๋๋ค.
public class Singleton {
private volatile static Singleton instance;
private Sigleton() {}
// Lazy Initialization. DCL
public Singleton getInstance() {
if(instance == null) {
synchronized(Singleton.class) {
if(instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
์ ์ฝ๋์์ `volatile`ํค์๋๊ฐ ๋ฑ์ฅํ๋๋ฐ, volatile ํค์๋๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฉํฐ์ค๋ ๋ ํ๊ฒฝ์์๋ ๊ฐ์ฒด๊ฐ Sigleton ์ธ์คํด์ค๋ก ์ด๊ธฐํ ๋๋ ๊ณผ์ ์ด ์ฌ๋ฐ๋ฅด๊ฒ ์งํ๋๋๋ก ํ ์ ์์ต๋๋ค.
[์ฐธ๊ณ ]
6. Lazy Initialization, LazyHolder (๊ฒ์ผ๋ฅธ ํ๋, Thread - safe)
Bill Pugh Singleton Implementaion ๋ผ๊ณ ๋ ๋ถ๋ฆ ๋๋ค.
Bill Pugh๊ฐ ๊ณ ์ํ ๋ฐฉ์์ผ๋ก, inner static helper class๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ์์ธ๋ฐ,
volatile ์ด๋ synchronized ํค์๋ ์์ด๋ ๋์์ฑ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ๋๋ฌธ์ ์ฑ๋ฅ์ด ๋ฐ์ด๋๋ฉฐ ํ์ฌ ๊ฐ์ฅ ๋๋ฆฌ ์ฐ์ด๋ ์ฑ๊ธํค ๊ตฌํ ๋ฐฉ๋ฒ์ ๋๋ค.
public class Singleton {
private Singleton() {}
private static class InnerInstanceClazz {
// ํด๋์ค ๋ก๋ฉ ์์ ์์ ์์ฑ
private static final Singleton uniqueInstance = new Singleton();
}
public static Singleton getInstance() {
return InnerInstanceClazz.uniqueInstance;
}
}
๋ฐฉ๋ฒ
- private inner static class๋ฅผ ๋์ด ์ฑ๊ธํค ์ธ์คํด์ค๋ฅผ ๊ฐ๊ฒ ํฉ๋๋ค
- InnerInstanceClazzํด๋์ค๋ Singleton ํด๋์ค๊ฐ Load ๋ ๋์๋ Load ๋์ง ์๋ค๊ฐ getInstance()๊ฐ ํธ์ถ๋์ ๋ ๋น๋ก์ JVM ๋ฉ๋ชจ๋ฆฌ์ ๋ก๋๋๊ณ , ์ธ์คํด์ค๋ฅผ ์์ฑํ๊ฒ ๋ฉ๋๋ค.
7. Enum Singleton (Thread - safe)
์์ 1~6๋ฒ์์ ์ดํด๋ณธ ๋ฐฉ๋ฒ๋ค์ ์ฌ์ค ์์ ํ ์์ ํ ์๋ ์์ต๋๋ค.
Java์ ๋ฆฌํ๋ ์ (Reflection)์ ํตํด์ ์ฑ๊ธํค์ ํ๊ดดํ ์ ์๊ธฐ ๋๋ฌธ์ ๋๋ค.
์ถ๊ฐ๋ก ์ง๋ ฌํ - ์ญ์ง๋ ฌํ ๊ณผ์ ์์๋ ์ฑ๊ธํค์ด ํ๊ดด๋ ์ ์์ต๋๋ค.
์ด์ Enum์ผ๋ก ์ฑ๊ธํค์ ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ด ๋ฑ์ฅํฉ๋๋ค.
public enum Singleton {
INSTANCE;
}
Enum ์ธ์คํด์ค์ ์์ฑ์ ๊ธฐ๋ณธ์ ์ผ๋ก Thread-safe ํฉ๋๋ค.
Enum ์ ์ฌ์ฉํ ๋ฐฉ์์ ์ฅ์ ์ ์์ฃผ ๋ณต์กํ ์ง๋ ฌํ ์ํฉ์ด๋, ๋ฆฌํ๋ ์ ๊ณต๊ฒฉ์๋ ์ 2์ ์ธ์คํด์ค๊ฐ ์์ฑ๋๋ ๊ฒ์ ๋ง์์ค๋ค๋ฐ ์์ต๋๋ค.
๋จ, ๋ง๋ค๋ ค๋ ์ฑ๊ธํด์ด Enum ์ธ์ ํด๋์ค๋ฅผ ์์ํด์ผ ํ๋ ๊ฒฝ์ฐ์๋ ์ฌ์ฉํ ์ ์์ผ๋ฉฐ, ๋ํ Android ๊ฐ์ด Context ์์กด์ฑ์ด ์๋ ํ๊ฒฝ์ผ ๊ฒฝ์ฐ, ์ฑ๊ธํด์ ์ด๊ธฐํ ๊ณผ์ ์ Context ๋ผ๋ ์์กด์ฑ์ด ๋ผ์ด๋ค ๊ฐ๋ฅ์ฑ์ด ์์ต๋๋ค.
์ฑ๊ธํค ํจํด์ ๋ฌธ์ ์
- ์ฑ๊ธํค ํจํด์ ๊ตฌํํ๋ ์ฝ๋ ์์ฒด๊ฐ ๋ง์ด ํ์ํฉ๋๋ค.
- ์์กด๊ด๊ณ์ ํด๋ผ์ด์ธํธ๊ฐ ๊ตฌ์ฒด ์ฝ๋์ ์์กดํ๋ฏ๋ก DIP(์์กด๊ด๊ณ ์ญ์ ์์น)๋ฅผ ์๋ฐํฉ๋๋ค ( ex : ๊ตฌ์ฒดํด๋์ค.getInstance())
- ํด๋ผ์ด์ธํธ๊ฐ ๊ตฌ์ฒด ์ฝ๋์ ์์กดํ๋ฏ๋ก OCP(๊ฐ๋ฐฉ-ํ์ ์์น)๋ฅผ ์๋ฐํ ๊ฐ๋ฅ์ฑ์ด ๋์ต๋๋ค.
- ํ ์คํธํ๊ธฐ ์ด๋ ต์ต๋๋ค
- ๋ด๋ถ ์์ฑ์ ๋ณ๊ฒฝํ๊ฑฐ๋ ์ด๊ธฐํํ๊ธฐ ์ด๋ ต์ต๋๋ค
- private ์์ฑ์๋ก ์์ ํด๋์ค๋ฅผ ๋ง๋ค๊ธฐ ์ด๋ ต์ต๋๋ค.
- ๊ฒฐ๋ก ์ ์ผ๋ก ์ ์ฐ์ฑ์ด ๋จ์ด์ง๋๋ค
์์ ๊ฐ์ ์ด์ ๋ค ๋๋ฌธ์ ์ํฐํจํด์ด๋ผ ๋ถ๋ฆฌ๊ธฐ๋ ํฉ๋๋ค.
์ฑ๊ธํค ์ปจํ ์ด๋
์คํ๋ง ์ปจํ ์ด๋๋ ์์ ๊ฐ์ ์ฑ๊ธํค ํจํด์ ๋ฌธ์ ์ ์ ํด๊ฒฐํ๋ฉด์, ๊ฐ์ฒด ์ธ์คํด์ค๋ฅผ ์ฑ๊ธํค์ผ๋ก ๊ด๋ฆฌํ์ฌ ์ค๋๋ค.
- ์คํ๋ง ์ปจํ
์ด๋๋ ์ฑ๊ธํค ํจํด์ ์ ์ฉํ์ง ์์๋, ๊ฐ์ฒด ์ธ์คํด์ค๋ฅผ ์ฑ๊ธํค์ผ๋ก ๊ด๋ฆฌํฉ๋๋ค.
- ์ฑ๊ธํค ์ปจํ ์ด๋์ ์์ฑ ๊ณผ์ ์ ๋ณด๋ฉด, ์ปจํ ์ด๋๋ ์คํ๋ง ๋น ๊ฐ์ฒด๋ฅผ ํ๋๋ง ์์ฑํด์ ๊ด๋ฆฌํฉ๋๋ค.
- ์คํ๋ง ์ปจํ
์ด๋๋ ์ฑ๊ธํค ์ปจํ
์ด๋ ์ญํ ์ ํฉ๋๋ค.
- ์ด๋ ๊ฒ ์ฑ๊ธํค ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ๊ด๋ฆฌํ๋ ๊ธฐ๋ฅ์ ์ฑ๊ธํค ๋ ์ง์คํธ๋ฆฌ๋ผ ํฉ๋๋ค.
- ์คํ๋ง ์ปจํ ์ด๋์ ์ด๋ฐ ๊ธฐ๋ฅ ๋๋ถ์ ์ฑ๊ธํค ํจํด์ ๋ชจ๋ ๋จ์ ์ ํด๊ฒฐํ๋ฉด์ ๊ฐ์ฒด๋ฅผ ์ฑ๊ธํค์ผ๋ก ์ ์งํ ์ ์์ต๋๋ค.
- ์ฑ๊ธํค ํจํด์ ์ํ ์ง์ ๋ถํ ์ฝ๋๊ฐ ๋ค์ด๊ฐ์ง ์์๋ ๋ฉ๋๋ค.
- DIP, OCP, ํ ์คํธ, private ์์ฑ์๋ก๋ถํฐ ์์ ๋กญ๊ฒ ์ฑ๊ธํค์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
์ฑ๊ธํค ๋ฐฉ์์ ์ฃผ์์
์ฑ๊ธํค ๋ฐฉ์์์๋ ์ฌ๋ฌ ํด๋ผ์ด์ธํธ๊ฐ ํ๋์ ๊ฐ์ ๊ฐ์ฒด ์ธ์คํด์ค๋ฅผ ๊ณต์ ํ๊ธฐ ๋๋ฌธ์
์ฑ๊ธํค ๊ฐ์ฒด๋ ์ํ๋ฅผ ์ ์ง(stateful)ํ๊ฒ ์ค๊ณํ๋ฉด ์๋ฉ๋๋ค.
๋ฌด์ํ(stateless)๋ก ์ค๊ณํด์ผ ํฉ๋๋ค
๋ฌด์ํ๋?
- ํน์ ํด๋ผ์ด์ธํธ์ ์์กด์ ์ธ ํ๋๊ฐ ์์ผ๋ฉด ์๋ฉ๋๋ค.
- ๊ฐ์ ๋ณ๊ฒฝํ ์ ์๋ ํ๋๊ฐ ์์ผ๋ฉด ์๋ฉ๋๋ค.
- ๊ฐ๊ธ์ ์ฝ๊ธฐ๋ง ๊ฐ๋ฅํด์ผ ํฉ๋๋ค.
- ํ๋ ๋์ ์ ์๋ฐ์์ ๊ณต์ ๋์ง ์๋, ์ง์ญ๋ณ์, ํ๋ผ๋ฏธํฐ, ThreadLocal๋ฑ์ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
Reference
'๐๏ธ Spring > ๊ธฐ๋ณธ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Spring] @ComponentScan (0) | 2021.12.11 |
---|---|
[Spring] @Configuration (0) | 2021.12.11 |
[Spring] ์คํ๋ง ์ปจํ ์ด๋์ ์คํ๋ง ๋น (0) | 2021.12.11 |
[Spring] IoC์ DI (0) | 2021.12.11 |
[Spring] ์คํ๋ง์ด๋? (0) | 2021.12.11 |