ํ ๋น์์คํ๋ง#2 ์ฑ๊ธํค ๋ ์ง์คํธ๋ฆฌ์ ์ค๋ธ์ ํธ ์ค์ฝํ
by JiwonDev2021.08.14 - [Backend/Spring Core] - ํ ๋น์ ์คํ๋ง#1 ์ค๋ธ์ ํธ์ ์์กด๊ด๊ณ

์์์ ์ธ๊ธํ ์ด ๋ด์ฉ์ ๋ํด์ ์กฐ๊ธ ๋ ์์ธํ๊ฒ ์์๋ณด์.
# ์ค๋ธ์ ํธ์ ๋์ผ์ฑ๊ณผ ๋๋ฑ์ฑ
'์๋ฐ์์ ๋ ๊ฐ์ ์ค๋ธ์ ํธ๊ฐ ๊ฐ์๊ฐ?' ๋ผ๋ ๋ง์ ์ฃผ์ํด์ ์ฌ์ฉํด์ผํ๋ค. ๋์ผ์ฑ(Identity)์ ๋๋ฑ์ฑ(Equality)์ ์ฐจ์ด๊ฐ ์๊ธฐ ๋๋ฌธ์ด๋ค.
- ๋์ผ์ฑ ๋น๊ต(==, Identity)๋ ๊ฐ๋ฅดํค๊ณ ์๋ ๊ฐ์ฒด๊ฐ ๋์ผํ ๊ฒฝ์ฐ์ ์ฌ์ฉํ๋ ๋ง์ด๋ค.
- ๋๋ฑ์ฑ ๋น๊ต(.equal() .hashtag(), Equality)๋ ๊ฐ์ฒด๊ฐ ๊ฐ์ง ๊ฐ, ์ ๋ณด๊ฐ ๋์ผํ ๊ฒฝ์ฐ ์ฌ์ฉํ๋ ๋ง์ด๋ค.
์ค๋ธ์ ํธ๊ฐ ๋์ผํ๋ฉด ๋๋ฑ์ฑ์ ๋ง์กฑํ์ง๋ง, ๋ฐ๋๋ก ๋๋ฑํ๋ค๊ณ ํด์ ๋์ผํ ๊ฐ์ฒด์์ ๋ณด์ฅํ ์ ์๋ค. ์ดํด๊ฐ ์๋๋ค๋ฉด ์๋๊ธ์ ์ฐธ๊ณ ํด๋ณด์. 2021.07.27 - [๊ธฐ๋ณธ ์ง์/Java ๊ธฐ๋ณธ์ง์] - .equals์ .hashCode()๋ ํญ์ ํจ๊ป ์ค๋ฒ๋ผ์ด๋ฉํด์ผํ๋ค.
.equals์ .hashCode()๋ ํญ์ ํจ๊ป ์ค๋ฒ๋ผ์ด๋ฉํด์ผํ๋ค.
Object ๋ฉ์๋์ ์๋ .hashCode() ๋ฉ์๋๋ ํด๋น ๊ฐ์ฒด์ ์ฃผ์๊ฐ์ ์ด์ฉํ์ฌ ๋ง๋ ๊ฐ์ฒด๋ง์ ๊ณ ์ ํ ์ ์ ๊ฐ์ ๊ฐ์ง๋ค. equals()๋ฅผ ์ค๋ฒ๋ผ์ด๋ฉ ํ ๋์๋ ๋ฐ๋์ hashCode()๋ ๋์ผํ ๊ฒฐ๊ณผ๋ฅผ ๋ด๋๋ก ํจ๊ป ์ค
jiwondev.tistory.com
# ์คํ๋ง์์์ ๋น ๊ฐ์ฒด
์ปจํ ์ด๋ (Object Factory)์์ ๊ฐ์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ฒ ๋๋ฉด ๋ ๊ฐ์ฒด๊ฐ ๊ฐ์ง ๊ฐ์ ๊ฐ์ง๋ง, ์ค์ ๋ฑ๋ก๋ ๊ฐ์ฒด๋ ๋ค๋ฅธ ๊ฐ์ฒด์ด๋ค. ์ฆ '๋๋ฑ์ฑ'์ ๋ง์กฑํ๋ '๋์ผ์ฑ'์ ๋ง์กฑํ์ง ์๋๋ค. ๊ฐ์ฒด๋ฅผ ์์ฑ ํ ๋๋ง๋ค ์ค๋ณตํด์ ๋ง๋ค๊ฒ๋๋ค.
DaoFactory factory = new DaoFactory(); // AppConfig ๊ฐ์ฒด๋ฅผ ์๋ฏธํ๋ค.
// ์ด ๋ ๊ฐ์ฒด๋ ๋ค๋ฅด๋ค.
UserDao dao1 = factory.userDao();
UserDao dao2 = factory.userDao();
// my.package.UserDao@118f375
// my.package.UserDao@117A8bd
System.out.println(dao1 + "\n" + dao2);
์คํ๋ง์์๋ ์ด๋ฌํ ์ค๋ณต(๋ญ๋น)๋ฅผ ๋ง๊ธฐ์ํด ๊ฐ์ฒด๋ฅผ ์ฑ๊ธํค์ผ๋ก ๋ฑ๋กํ๋ค.
// Object Factory ๊ฐ์ฒด๋ฅผ ์คํ๋ง ์ค์ ํ์ผ๋ก ๋๊ฒจ์ฃผ์ด, ์คํ๋ง ์ปจํ
์ด๋๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ
ApplicationContext context = new AnnotationConfigApplicationContext(DaoFactory.class);
// ๊ทธ๋ ๋ค๋ฉด ์ด ๋ ๊ฐ์ฒด๋ ๋์ผ์ฑ์ ๋ง์กฑํ์ง ๋ชปํ๋ ๊ฑธ๊น?
UserDao dao1 = context.getBean("userDao", UserDao.class);
UserDao dao2 = context.getBean("userDao", UserDao.class);
// ๋๋๊ฒ๋ ๋์ผ์ฑ์ ๋ง์กฑํ๋ค. ๋ช ๊ฐ๋ฅผ ์์ฑํ๋ ๋์ผํ ํ๋์ ๊ฐ์ฒด๋ง ์์ฑํ๊ณ , ์ฐธ์กฐํ๋ค.(์ฑ๊ธํค)
// my.package.UserDao@ee22f7
// my.package.UserDao@ee22f7
System.out.println(dao1 + "\n" + dao2);
# ์ฑ๊ธํค ๋ ์ง์คํธ๋ฆฌ๋ก์ ApplicationContext
์คํ๋ง์์ ์ฌ์ฉํ๋ ์ปจํ ์ด๋, Application Context๋ ์ฐ๋ฆฌ๊ฐ ์์์ ๋ง๋ค์๋ Object Factory์ ๋น์ทํ ๋ฐฉ์์ผ๋ก ๋์ํ๋ค. ํ์ง๋ง ์คํ๋ง ์ปจํ ์ด๋๋ ์ด์ ๋์์ ์ฑ๊ธํค์ ์ ์ฅํ๊ณ ๊ด๋ฆฌํ๋ ์ฑ๊ธํค ๋ ์ง์คํธ๋ฆฌ(singleton registry) ์ด๊ธฐ๋ ํ๋ค.
์คํ๋ง์ ํ์์ ๋ฐ๋ผ ๋ฐ๋ก ์ค์ ํ๋ ๊ฒ ์๋๋ผ๋ฉด, ๊ธฐ๋ณธ์ ์ผ๋ก ์์ฑํ๋ ๋น ๊ฐ์ฒด๋ ์ ๋ถ ์ฑ๊ธํค์ผ๋ก ๋ง๋ ๋ค. ๋์์ธ ํจํด์์ ๋์ค๋ ์ฑ๊ธํค ํจํด๊ณผ ๋น์ทํ ๊ฐ๋ ์ด์ง๋ง, ๊ตฌํ๋ฐฉ๋ฒ์ ํ์ฐํ ๋ค๋ฅด๋ค.

@ ์ฝ๋๋ก ๊ตฌํํ ์ฑ๊ธํค์ ํ๊ณ
๊ทผ๋ฐ ์ด๋ ๊ฒ ๋ฐ์ดํธ์ฝ๋๋ฅผ ์กฐ์ํ๋ฉด์๊น์ง ์ฑ๊ธํค์ ๊ตฌํํด์ผ ํ๋ ์ด์ ๋ ๋ฌด์์ผ๊น? ๊ทธ ์ด์ ๋ ์คํ๋ง์ ํ์์ ์ผ๋ก ์๋ฒ(์น ์๋ฒ)์ ์ฃผ๋ก ์ฌ์ฉ๋๋ ํ๋ ์์ํฌ์ด๊ธฐ ๋๋ฌธ์ด๋ค. ์คํ๋ง์ด ์ฒ์ ์ค๊ณ๋์๋ ๋๊ท๋ชจ ์๋น์ค๋ฅผ ์ฒ๋ฆฌํ๋ ์๋ฒํ๊ฒฝ์ ์ด๋น ์์ญ, ์๋ฐฑ๋ฒ์ ์ด๋ฅด๋ ํด๋ผ์ด์ธํธ์ ์์ฒญ์ ์ฒ๋ฆฌํ๋ค. ๊ทธ ํ๋์ ์์ฒญ์ ์ฒ๋ฆฌํ๊ธฐ ์ํด [๋ฐ์ดํฐ ์์ธ์ค(DB) ๊ฐ์ฒด, ์๋น์ค ๊ฐ์ฒด, ํต์ฌ ๋น์ฆ๋์ค ๋ก์ง ๊ฐ์ฒด]๋ฑ ์๋ง์ ๊ฐ์ฒด๋ค์ด ์ฐธ์ฌํ๋ ๊ณ์ธต์ ์ธ ๊ตฌ์กฐ๋ก ์ด๋ฃจ์ด์ง๋๊ฒ ๋๋ถ๋ถ์ด๋ค.
๋งค๋ฒ ํด๋ผ์ด์ธํธ์ ์์ฒญ์ด ์ฌ ๋๋ง๋ค ๊ฐ ๋ก์ง์ ๋ด๋นํ๋ ๊ฐ์ฒด๋ฅผ ์๋ก ๋ง๋ ๋ค๊ณ ์๊ฐํด๋ณด์. ์ด๋น 500๊ฐ์ ์์ฒญ์ด ๋ค์ด์จ๋ค๋ฉด 2500๊ฐ์ ์๋ก์ด ๊ฐ์ฒด๊ฐ ์์ฑ๋๋ค. 1๋ถ์ด๋ฉด ์ญ๋ง๊ฐ, ํ์๊ฐ์ด๋ฉด ์๋ฒ์ 900๋ง๊ฐ์ ์ค๋ธ์ ํธ๊ฐ ์์ฑ๋๊ณ ์ฌ์ฉ๋ ๊ฒ์ด๋ค. ์๋ฌด๋ฆฌ JVM๊ณผ GC์ ๊ธฐ๋ฅ์ด ์ข์์ก๋ค๊ณ ํ๋ค, ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ์๋ฉธ์ํค๋ ๊ณผ์ ์ ์ฐ์ฐ ๋น์ฉ์ด ๋น์ผ ์์ ์ด๋ค. ๊ทธ๋์ ์ฌ๋ฌ ์ค๋ ๋์์ ํ๋์ ๊ฐ์ฒด๋ฅผ ๊ณต์ ํด ๋๋ ค์ฐ๋๋ก ์ฑ๊ธํค์ ๊ตฌํํ๋ ๊ฒ์ด๋ค.
๋ค๋ง ์ฝ๋๋ก๋ ์ฑ๊ธํค์ ๊ตฌํํ ์๋ ์๋ค. ํ์ง๋ง ์ค์ ์๋น์ค์์ ์ฌ์ฉํ๊ธฐ์๋ ์๋์ ๊ฐ์ ํ๊ณ์ ์ด ์๋ค.
public class DoubleLockSingleton {
// ๋จ์ํ ์ฑ๊ธํค ๊ตฌํ ๋ฐฉ๋ฒ
private static final Singleton instance = new Singleton();
// private ์์ฑ์๋ฅผ ์ด์ฉํ์ฌ ๊ฐ์ ๊ฐ์ฒด๊ฐ ์ค๋ณต ์์ฑ๋๋ ๊ฒ์ ๋ง์.
private Singleton(){}
public static Singleton getInstance(){
// ๋ฉํฐ์ค๋ ๋์์ ์ฑ๊ธํค ๊ฐ์ฒด ์์ฑ์ Thread-safety ๋ณด์ฅ
if(instance == null){
synchronized (Singleton.class) {
if(instance == null)
instance = new Singleton();
}
}
return instance;
}
}
- private ์์ฑ์ ๋๋ฌธ์ ๊ฐ์ฒด๋ฅผ ์์ํ ์ ์๋ค. ์๋น์ค ๊ฐ์ฒด์ ๋คํ์ฑ์ ์ ์ฉํ๊ธฐ ์ด๋ ต๋ค.
- ์ค์ ๊ฐ์ฒด๊ฐ ์๋ ํ ์คํธ์ฉ ๊ฐ์ฒด(mock)๋ฅผ ์ฌ์ฉํ๊ธฐ ์ด๋ ต๋ค. ์ฆ ํ ์คํธ ํ๊ฒฝ๊ตฌ์ฑ์ด ์ด๋ ค์์ง๋ค.
- ๋ถ์ฐ๋ ์๋ฒํ๊ฒฝ์์ ์ฑ๊ธํค์ด ํ๋๋ง ๋ง๋ค์ด์ง๋ ๊ฒ์ ๋ณด์ฅํ์ง ๋ชปํ๋ค. (์๋ฒ์ JVM์ด ์ฌ๋ฌ๊ฐ์ด๋ค)
- ์ฑ๊ธํค ๊ฐ์ฒด๊ฐ '์ ์ญ ๋ณ์'์ฒ๋ผ ์ฌ์ฉ๋ ์ ์๋ ๊ฐ๋ฅ์ฑ์ ๊ฐ์ง๊ณ ์๋ค. ์ด๋ฌํ ๋ฐฉ์์ side-effect๋ฅผ ์ ๋ฐํ๋ค.
๊ทธ๋์ ์คํ๋ง์ ๋ฐ์ดํธ์ฝ๋ ์กฐ์์ ํตํด ์ง์ ์ฑ๊ธํค ํํ์ ์ค๋ธ์ ํธ๋ฅผ ๋ง๋ค๊ณ ๊ด๋ฆฌํ๋ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋๋ฐ, ์ด๋ฅผ ์ฑ๊ธํค ๋ ์ง์คํธ๋ฆฌ๋ผ๊ณ ๋ถ๋ฅธ๋ค. ์ฑ๊ธํค ๋ ์ง์คํธ๋ฆฌ๋ ์ฝ๋ ์์์ static ๋ฉ์๋์ private ์์ฑ์๋ฅผ ์ด์ฉํด์ผํ๋ ๋น์ ์์ ์ธ ์ฑ๊ธํค ํด๋์ค๊ฐ ์๋๋ผ, ํ๋ฒํ ์๋ฐ ํด๋์ค๋ฅผ ์ฑ๊ธํค ๊ฐ์ฒด๋ก ์ฌ์ฉํ ์ ์๊ฒ ๋ง๋ค์ด์ค๋ค.
์ฑ๊ธํค ๋ ์ง์คํธ๋ฆฌ๋ ์ฑ๊ธํค ํจํด๊ณผ ๋ฌ๋ฆฌ ์๋ฐ์ ๊ฐ์ฒด์งํฅ์ ์ธ ์ค๊ณ ๋ฐฉ์์ด๋ ์ฝ๋๋ฅผ ํ์ฉํ๋๋ฐ ์๋ฌด๋ฐ ์ ์ฝ์ด ์๋ค๋ ํฐ ์ฅ์ ์ด ์๋ค. ๋ค๋ง '์ฑ๊ธํค' ํจํด์ด ๊ฐ์ง๋ ์ํ์ฑ์ ๋ณํจ์ด ์๊ธฐ์, ์ฃผ์ํด์ ์ฌ์ฉํ๋ ๊ฒ์ ์์ผ๋ฉด ์๋๋ค.
@ ์ฃผ์! ์ฑ๊ธํค๊ณผ ์ค๋ธ์ ํธ ์ํ
์ฑ๊ธํค์ ๋ฉํฐ์ค๋ ๋ ํ๊ฒฝ์ด๋ผ๋ฉด ์ฌ๋ฌ ์ค๋ ๋๊ฐ ๋์์ ์ ๊ทผํด์ ์ฌ์ฉํ ์ ์๋ค. ๋ฐ๋ผ์ '๊ฐ์ฒด'๊ฐ ์ํ ๊ฐ์ ๊ฐ์ ธ์๋ ์๋๋ค. ์ํ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ง๊ณ ์์ง ์๋ Stateless ๋ฐฉ์์ผ๋ก ์ฑ๊ธํค์ ์ฌ์ฉํด์ผํ๋ค.
๋ ์ฝ๊ฒ ๋งํ๋ฉด ์ฑ๊ธํค ์ค๋ธ์ ํธ์ ์ธ์คํด์ค ๋ณ์๋ฅผ ์์ ํ๋ ์์ ์ ๋งค์ฐ ์ํํ๋ค๋ ๋ง์ด๋ค. ์ฌ๋ฌ ์ค๋ ๋์์ ์ฌ์ฉ๋ ๊ฐ๋ฅ์ฑ์ด ์๊ธฐ์ Thread-Safetyํ์ง ์๋ค. ๋ ํฐ ๋ฌธ์ ๋ ์คํ๋ง์์ ์ฑ๊ธํค ๋ ์ง์คํธ๋ฆฌ๋ฅผ ํตํด ๊ด๋ฆฌํด์ฃผ๋ค๋ณด๋, ๊ฐ๋ฐ์๊ฐ '์ฑ๊ธํค ๊ฐ์ฒด'๋ผ๋ ์ฌ์ค์ ์๊ณ ์ํ๋ฅผ ์ ์ฅํ ์ ์๋ค๋ ์ํ์ฑ์ด ์๋ค.
๋ฉํฐ์ค๋ ๋ ํ๊ฒฝ์์ ์ด๋ฌํ ์ค๋ฅ๊ฐ ๋ฐ์ํ๊ฒ๋๋ฉด, ๊ทธ ์ค๋ฅ๋ฅผ ์ก๋ ๊ฒ์ ์์ ์ด์์ผ๋ก ์ด๋ ต๋ค. ์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธ์ ํ๋๋ฐ ๋ค๋ฅธ์ฌ๋์ ๋ฐ์ดํฐ๊ฐ ๋ณด์ด๋ ์ํฉ์ด๋ผ๋ฉด, ์ด๋์๋ถํฐ ์ด๋ค ์ฝ๋๋ฅผ ๋๋ฒ๊น ํด์ผํ ๊น ์์ํด๋ณด์. ์ ๋ง ๋ต ์๋ ์ํฉ์ด๊ณ , ์ค์ ํ์ ์์๋ ์ข ์ข ๋ฐ์ํ๋ ์ผ์ด๊ธฐ๋ ํ๋ค. ๊ทธ๋ฌ๋ ์ ๋ฐ ์คํ๋ง ๋น ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ ๋ ๊ธฐ๋ณธ๊ฐ์ด ์ฑ๊ธํค ๊ฐ์ฒด์์ ์์ง๋ง๊ณ ์ฃผ์ํด์ 'Stateless'ํ๊ฒ ์ฌ์ฉํ๋๋ก ํ์.
@ ์ฑ๊ธํค์ด ์๋ ๋น ๊ฐ์ฒด
์คํ๋ง์์ ๊ด๋ฆฌํ๋ ์ค๋ธ์ ํธ, ์ฆ ๋น์ด ์์ฑ๋๊ณ ์กด์ฌํ๊ณ ์ ์ฉ๋๋ ๋ฒ์๋ฅผ ์คํ๋ง์์๋ ๋น์ ์ค์ฝํ(Scope)๋ผ๊ณ ๋ถ๋ฅธ๋ค. ๊ธฐ๋ณธ ๊ฐ์ธ ์ฑ๊ธํค ์ค์ฝํ๋ ์คํ๋ง ์ปจํ ์ด๋๊ฐ ์คํ๋๋ ์์ ์ ์์ฑ๋๊ณ , ์ข ๋ฃ๋๋ ์์ ์ ์๋ฉธ๋๋ค.
๋ค๋ง ํ์์ ๋ฐ๋ผ์๋ ์ฑ๊ธํค ์ธ์ ๋ค๋ฅธ ์ค์ฝํ๋ฅผ ๊ฐ์ง ์ ์๋ค.
- prototype ์ค์ฝํ๋ ์ฑ๊ธํค ์ค์ฝํ์ ๋ฌ๋ฆฌ ๋น์ ์์ฒญํ ๋ ๋ง๋ค ์๋ก์ด ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด์ค๋ค.
- request ์ค์ฝํ๋ HTTP ์์ฒญ์ด ์์ ๋ ๋น์ด ์์ฑ๋๊ณ , ์์ฒญ์ด ๋๋ฌ์ ๋ ๋น์ด ๋ฐํ๋๋ค.
- session ์ค์ฝํ๋ ์น ์ธ์ ๊ณผ ์ ์ฌํ๊ฒ ์ฌ์ฉํ ์ ์๋ค.
๋ค๋ง ์ด ๋ด์ฉ์ ์คํ๋ง์ ๋ํ ๊ธฐ์ด์ง์์ด ์์ด์ผ ์ดํดํ๊ธฐ ์ฌ์ฐ๋ฏ๋ก, ๋์ค์ ์ค์ฝํ๋ค์ ๋ฐ๋ก ๋ค๋ฃจ๋๋ก ํ๊ฒ ๋ค.
2021.08.03 - [Backend/Spring Core] - #11 ๋น ์ค์ฝํ(+Provider, ํ๋ก์ ๋ชจ๋)
#11 ๋น ์ค์ฝํ(+Provider, ํ๋ก์ ๋ชจ๋)
์์์ ์ฐ๋ฆฌ๋ ์คํ๋ง ๋น์ ์คํ๋ง ์ปจํ ์ด๋์ ์์๊ณผ ํจ๊ป ์์ฑ๋๊ณ , ์ปจํ ์ด๋๊ฐ ์ข ๋ฃ๋ ๋ ๊น์ง ์ ์ง๋๋ค๊ณ ํ์ตํ๋ค. ์ด๋ ์คํ๋ง ๋น์ด ๊ธฐ๋ณธ์ ์ผ๋ก '์ฑ๊ธํค ์ค์ฝํ'๋ก ์์ฑ๋๊ธฐ ๋๋ฌธ์ด๋ค. ์ฌ
jiwondev.tistory.com
'๐ฑ Spring Framework > Spring Core' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| DB์ @Transactional์ ์ฌ์ฉํ ๋ ์์ฃผ ๋์ค๋ ์ค์ (0) | 2021.08.18 |
|---|---|
| @Transactional ์ ๋์์๋ฆฌ, ํธ๋์ญ์ ๋งค๋์ (5) | 2021.08.18 |
| ํ ๋น์ ์คํ๋ง#1 ์ค๋ธ์ ํธ์ ์์กด๊ด๊ณ (0) | 2021.08.14 |
| #11 ๋น ์ค์ฝํ(+Provider, ํ๋ก์ ๋ชจ๋) (0) | 2021.08.03 |
| #10 ๋น ์๋ช ์ฃผ๊ธฐ ์ฝ๋ฐฑ (0) | 2021.08.03 |
๋ธ๋ก๊ทธ์ ์ ๋ณด
JiwonDev
JiwonDev