μ±κΈν€ ν¨ν΄μ λν΄μ (Keyword : μ±κΈν€ λμμΈ ν¨ν΄)
π‘ λ€μ΄κ°κΈ° μ μ
무νμΌλ‘ μ‘΄μ¬νλ μμμ μ‘΄μ¬νμ§ μλλ€. μ»΄ν¨ν°κ° μ 곡νλ μμ λ§μ°¬κ°μ§λ‘ μ νλμ΄ μλ€.
μ΄λ¬ν μν©μμ μΈμ€ν΄μ€κ° λ¨μ©λλ κ²μ λ°λμ§νμ§ μκ³
νλμ μμμΌλ‘ λͺ¨λκ° κ³΅μ ν΄μ μ¬μ©ν΄μΌνλ κ²½μ° μ±κΈν€ ν¨ν΄μ μ μ©ν λ°©λ²μ΄ λ μ μλ€.
π‘ μ±κΈν€ ν¨ν΄(Singleton pattern)μ΄λ?
μννΈμ¨μ΄ λμμΈ ν¨ν΄μμ μ±κΈν€ ν¨ν΄μ λ°λ₯΄λ ν΄λμ€λ, μμ±μκ° μ¬λ¬ μ°¨λ‘ νΈμΆλλλΌλ, μ€μ λ‘ μμ±λλ κ°μ²΄λ νλμ΄κ³ μ΅μ΄ μμ± μ΄νμ νΈμΆλ μμ±μλ μ΅μ΄μ μμ±μκ° μμ±ν κ°μ²΄λ₯Ό 리ν΄νλ€.
μ¦ μμ±μμ νΈμΆμ΄ λ°λ³΅μ μΌλ‘ μ΄λ€μ Έλ μ€μ λ‘ μμ±λλ κ°μ²΄λ μ΅μ΄ μμ±λ κ°μ²΄λ₯Ό λ°ν ν΄μ£Όλ κ²μ΄λ€.
π νλμ κ°μ²΄λ§μ μμ±ν΄ μ΄νμ νΈμΆλ κ³³μμλ μμ±λ κ°μ²΄λ₯Ό λ°ννμ¬ νλ‘κ·Έλ¨ μ λ°μμ νλμ μΈμ€ν΄μ€λ§μ μ¬μ©νκ² ν¨.
π μ΄λ€ ν΄λμ€κ° μ΅μ΄ νλ²λ§ λ©λͺ¨λ¦¬λ₯Ό ν λΉνκ³ (Static) κ·Έ λ©λͺ¨λ¦¬μ κ°μ²΄λ₯Ό λ§λ€μ΄ μ¬μ©νλ λμμΈ ν¨ν΄μ μλ―Έν¨.
λμμΈ ν¨ν΄μ μ λ°° κ°λ°μ λΆλ€μ΄ κ°λ°μ νμλ©΄μ,
μ΄λ°μμΌλ‘ κ°λ°μ νλ©΄ μ’λ€ μ΄λ° κ²λ€μ ν¨ν΄μΌλ‘ μ μνκ²μ΄λ€.
λ°λΌμ μ±κΈν€ ν¨ν΄λ λμμΈ ν¨ν΄ μ€ νλμ΄κ³ , κΌ μ¨μΌλλκ²μ μλλ€. μν©μ λ§κ² μ°λ©΄ λλ κ²μ΄λ€.
π‘ μ±κΈν€ ν¨ν΄ μμ
μλμ μμ λ μΈν°νμ΄μ€λ₯Ό ꡬνν BoardServiceImpl ν΄λμ€λ‘
μ±κΈν€ ν¨ν΄ ꡬν μ μΈν°νμ΄μ€μΈ IBoardServiceλ₯Ό νμ μΌλ‘ μ§μ ν λ€,
BoardServiceImpl μμ±μ νΈμΆ μ BoardDaoImplκ°μ²΄λ₯Ό μμ±νλ€.(λ€νμ± κ°λ )
public class BoardServiceImpl implements IBoardService{
private IBoardDao boardDao;
private Connection conn;
// μ±κΈν€ κ°μ²΄ μν μμ κ°μ²΄ μμ±
private static IBoardService boardService;
private BoardServiceImpl() {
boardDao = BoardDaoImpl.getInstance();
}
public static IBoardService getInstance() {
if(boardService == null) {
boardService = new BoardServiceImpl();
}
return boardService;
}
ν΄λμ€ λ³μμ μμ±μλ₯Ό μΈλΆμμ μμ±ν μ μλλ‘ μ νμ λμ΄
κ°μ²΄ μμ± μ νλμ κ°μ²΄μ μ£Όμλ§ μ¬μ©νλλ‘ ν μ μλ€.
π‘ μ±κΈν€ ν¨ν΄μ μ¬μ©?
μ£Όλ‘ κ³΅ν΅λ κ°μ²΄λ₯Ό μ¬λ¬κ° μμ±ν΄μ μ¬μ©νλ DBCP(DataBase Connection Pool)κ³Ό κ°μ μν©μμ λ§μ΄ μ¬μ©λλ€.
π‘ μ±κΈν€ ν¨ν΄μ μ¬μ©νλ μ΄μ λ?
νλ²μ κ°μ²΄ μμ±μΌλ‘ μ¬μ¬μ©μ΄ κ°λ₯νκΈ° λλ¬Έμ λ©λͺ¨λ¦¬ λλΉλ₯Ό λ°©μ§ν μ μλ€.
μ±κΈν€μΌλ‘ μμ±λ κ°μ²΄λ 무쑰건 νλ² μμ±μΌλ‘ μ μμ±μ λκΈ°μ λ€λ₯Έ κ°μ²΄μ 곡μ κ° μ©μ΄νλ€.
π‘ μ±κΈν€ ν¨ν΄μ λ¬Έμ μ
μ±κΈν€ ν¨ν΄μ μ μμ±μ λλ©΄μ
λ€λ₯Έ κ°μ²΄μ 곡ν΅μΌλ‘ μ¬μ©νλ κ²½μ°μ κ°μ λͺ κ°μ§ μΌμ΄μ€μμλ§ μ¬μ©ν λ ν¨μ¨μ μ΄λ©°
κ·Έ μΈμλ λ¬Έμ μ μ΄ μκΈΈ μ μλ€.
μ±κΈν€μΌλ‘ λ§λ κ°μ²΄μ μν μ΄ κ°λ¨ν κ²μ΄ μλ μν μ΄ λ³΅μ‘ν κ²½μ°λΌλ©΄
ν΄λΉ μ±κΈν€ κ°μ²΄λ₯Ό μ¬μ©νλ λ€λ₯Έ κ°μ²΄κ°μ κ²°ν¨λκ° λμμ Έμ
κ°μ²΄ μ§ν₯ μ€κ³ μμΉμ μ΄κΈλκ² λλ€. (κ°λ°©-νμ)
ν΄λΉ μ±κΈν€ κ°μ²΄λ₯Ό μμ ν κ²½μ°, μ±κΈν€ κ°μ²΄λ₯Ό μ¬μ©νλ κ³³μμ μ¬μ΄λ μ΄ν©νΈ λ°μν νλ₯ μ΄ μκΈ°κ² λλ©°
λ©ν° μ°λ λ νκ²½μμ λκΈ°ν μ²λ¦¬ λ¬Έμ λ±μ΄ μκΈ°κ² λλ€.
λ€μν μ±κΈν€μ ꡬν
π‘ static block
public class ExampleClass1 {
//Instance
private static ExampleClass1 instance;
//private construct
private ExampleClass1() {}
static {
try {instance = new ExampleClass1();}
catch(Exception e) { throw new RuntimeException(
"Create instance fail. error mse = " + e.getMessage());}
}
public static ExampleClass1 getInstance() {
return instance;
}
}
μμ κ°μ΄ static λΈλμ μ¬μ©ν κ²½μ° ν΄λμ€κ° λ‘λ©λ λ νλ²λ§ μ€νμ νκ²λλ νΉμ±μ μ¬μ©νλ€.
νμ§λ§ μΈμ€ν΄μ€κ° μ¬μ©λλ μμ μ΄ μλ ν΄λμ€ λ‘λ© μμ μ μ€νλλ€.
π‘ lazy init
μ static λ°©λ²μμ κ°μ νμ¬ ν΄λμ€ λ‘λ© μμ μ΄ μλ μΈμ€ν΄μ€κ° νμνμ¬ μμ²ν λ μμ±λλ ννλ‘ μμ±νμλ€.
π κΈ°λ³Έ μμ±μλ₯Ό privateλ‘ μμ±νμ¬ μΈλΆμμ μΈμ€ν΄μ€ μμ±μ λΆκ°λ₯νκ² νκ³ , getInstanceλ₯Ό ν΅ν΄μλ§ μμ±μ΄ κ°λ₯νκ² νλ€.
π getInstanceλ λ΄λΆμ μΌλ‘ μμ±λμ§ μμλ€λ©΄ κ°μ²΄λ₯Ό μμ±νκ³ κΈ°μ‘΄μ μμ±λ κ°μ΄ μ‘΄μ¬νλ©΄ μμ±λ μΈμ€ν΄μ€λ₯Ό 리ν΄νλ ννλ‘ νλ‘κ·Έλ¨ μ λ°μ κ±Έμ³ νλμ μΈμ€ν΄μ€λ₯Ό μ μ§νλ€.
π μΈμ€ν΄μ€λ₯Ό μ 곡νλ λ©μλμ μΈμ€ν΄μ€ λ³μλ λͺ¨λ StaticμΌλ‘ μ μΈλ μ μ λ³μ λ° λ©μλμ΄λ€.
π κΈ°λ³Έ μμ±μλ₯Ό ν΅ν΄ μμ±ν μ μκΈ° λλ¬Έμ μΈλΆμμ μΈμ€ν΄μ€μ μ κ·Όνλ €λ©΄ λΉμ°ν ν΄λμ€ λ³μ λ° λ©μλμ μ κ·Όμ νμ©ν΄μΌνκΈ° λλ¬Έμ λ λ©μλλ μ μ νμ μΌλ‘ μ μΈλλ€.
public class ExampleClass2 {
//Instance
private static ExampleClass2 instance;
//private construct
private ExampleClass2() {}
public static ExampleClass2 getInstance() {
if(instance == null) {instance = new ExampleClass2();}
return instance;
}
}
π νμ§λ§ μ ννλ‘ κ΅¬μ±ν κ²½μ° λ©ν° μ°λ λ(Multi-Thread) νκ²½μμ μ·¨μ½νλ€.
μ¬λ¬ μ°λ λκ° κ³΅μ λκ³ μλ μν©μμ μ‘°κ±΄λ¬Έμ΄ λμμ λλ² λ μ μκΈ° λλ¬Έμ
νΉμ μ°λ λκ° λμμ getInstance() λ©μλλ₯Ό νΈμΆνκ² λλ©΄ μΈμ€ν΄μ€κ° λλ² μμ±λλ λ¬Έμ κ° λ°μνλ€.
μλμ μ½λμμ count κ°μ κ°κΈ° λ€λ₯Έ μ°λ λμμ 곡μ νκ³ μκ³ μλ‘ λ€λ₯Έ νλ‘μΈμ€μμ μ²λ¦¬νκ³ μκΈ° λλ¬Έμ κ°μ΄ μΌκ΄λμ§ μμ μ μλ€.
public class ExampleClass5 {
//Instance
private static ExampleClass5 instance;
private int count = 0;
//private construct
private ExampleClass5() {}
public static ExampleClass5 getInstance() {
if(instance == null) {instance = new ExampleClass5();}
return instance;
}
public void print(String input) {
count++;
System.out.println(input + "count : " + count);
}
}
π‘ Thread safe + lazy (μ μ λ³μμ μΈμ€ν΄μ€λ₯Ό λ§λ€μ΄ λ°λ‘ μ΄κΈ°ν νλ λ°©λ²)
public class ExampleClass3 {
//Instance
private static ExampleClass3 instance;
//private construct
private ExampleClass3() {}
public static synchronized ExampleClass3 getInstance() {
if(instance == null) {instance = new ExampleClass3();}
return instance;
}
}
Lazyμμ 보μλ getInstance() λ©μλμ synchronized ν€μλλ₯Ό λΆμμΌλ‘μ¨ μ°λ λμμ λμ μ κ·Όμ λν λ¬Έμ λ₯Ό ν΄κ²°νμλ€.
νμ§λ§ synchronized ν€μλλ μ±λ₯ μ νλ₯Ό λ°μμν¨λ€.
π‘ Holder
public class ExampleClass4 {
//private construct
private ExampleClass4() {}
private static class InnerInstanceClazz() {
private static final ExampleClass4 instance = new ExampleClass4();
}
public static ExampleClass4 getInstance() {
return InnerInstanceClazz.instance;
}
}
JVMμ ν΄λμ€ λ‘λ λ©μ»€λμ¦κ³Ό ν΄λμ€μ λ‘λ μμ μ μ΄μ©νμ¬ λ΄λΆ ν΄λμ€λ₯Ό ν΅ν΄ μμ± μν΄μΌλ‘μ¨ μ°λ λ κ°μ λκΈ°ν λ¬Έμ λ₯Ό ν΄κ²°νλ€.
μ λ°©λ²μ νμ¬ Javaμμ μ±κΈν€ μμ±μμ μ¬μ©νλ λνμ μΈ λ°©λ²μ΄λ€.
νμ¬ λ΄κ° ν μ€νΈ ν λμλ μ μ½λμ μ€λ₯κ° μμλ€.
νμ¬ μ§μμΌλ‘λ μ€λ₯λ₯Ό μ‘μ§ λͺ»νλ€. κ·Έλμ λμ€μ μκ²λλ©΄ μ 리νλ €κ³ νλ€.
π‘ μ 리
μ±κΈν€ ν¨ν΄μ Spring framework μμλ λ§μ΄ μ¬μ©λλ©°, μ΄λ€μμΌλ‘ ꡬννλμ§ μμλλ©΄ λμμ΄ λλ€.
μλ°μ Spring μμμ μ±κΈν€ μ°¨μ΄μ μ΄λΌλ©΄, μ±κΈν€ κ°μ²΄μ μλͺ μ£ΌκΈ°κ° λ€λ₯΄λ€.
λν μλ°μμ 곡μ λ²μλ Class loader κΈ°μ€μ΄μ§λ§, Springμμλ ApplicationContextκ° κΈ°μ€μ΄ λλ€.
π μ±κΈν€μ νλ‘κ·Έλ¨ μ 체μμ νλμ κ°μ²΄λ§μ 곡ν΅μΌλ‘ μ¬μ©νκ³ μκΈ° λλ¬Έμ κ° κ°μ²΄κ°μ κ²°ν©λκ° λμμ Έμ λ³κ²½μ μ μ°νκ² λμ²ν μ μλ€.
π μ±κΈν€ κ°μ²΄κ° λ³κ²½λλ©΄ μ΄λ₯Ό μ°Έμ‘°νκ³ μλ λͺ¨λ κ°λ€μ΄ λ³κ²½λμ΄μΌ νλ―λ‘, λ©ν° μ°λ λ νκ²½μμ λμ²κ° μ΄λμ λ κ°λ₯νμ§λ§, κ³ λ €ν΄μΌ ν μμκ° λ§μ μ¬μ©μ΄ μ΄λ ΅κ³ νλ‘κ·Έλ¨ μ λ°μ κ±Έμ³μ νμν λΆλΆμλ§ μ¬μ©νλ€λ©΄ μ₯μ μ΄ μλ€. (ν¬μΈνΈλ₯Ό μ‘κΈ° μ΄λ ΅κΈ΄ νλ€.)
π μ μ ν ννλ‘ μ±κΈν€μ νμ©νλ©΄ μ’μ§λ§ λ¨μ©νκ² λ μ¬μ§κ° λ§λ€.
π λ©ν° μ°λ λ νκ²½μμμ μ±κΈν€
- Synchronizedλ₯Ό ν΅ν΄ κ΄λ¦¬νλ©΄ λλ©°, λ€μν λ³νμ λμνκΈ° μν΄ μΈν°νμ΄μ€μ ννλ‘ κ΄λ¦¬νλ©΄ μ’λ€.
π λ¨μΌ μ°λ λ νκ²½μμμ μ±κΈν€
- μ μ ν΄λμ€μ ννλ‘ μ¬μ©νλ©΄ λλ€. (ν΄λμ€ λ‘λ©λ¨κ³μμ λ°λ‘ μ΄κΈ°νλλλ‘)
- ν μ€νΈλ₯Ό μν λͺ¨μ κ°μ²΄λ₯Ό λ§λ€κ³ νΉμ λ€λ₯Έ λͺ©μ μΌλ‘ μ¬μ©νλ€λ©΄ λ©ν° μ°λ λ νκ²½μμ μ±κΈν€μ μ¬μ©νλ―μ΄ μ¬μ©νλ€.
μ°Έκ³ λΈλ‘κ·Έ