์์กด์ฑ ์ฃผ์ (DI)๋ ๋ฌด์์ ๋ป ํ๋๊ฐ?
์์กด์ฑ ์ฃผ์ ์ ์คํ๋ง ํ๋ ์์ํฌ์ ํต์ฌ ๊ธฐ์ ์ค ํ๋๋ก์จ, ๊ฐ์ฒด ๊ฐ์ ์์กด์ฑ(๊ฐ์ฒด ๊ฐ์ ์ฐ๊ฒฐ๊ด๊ณ)์ ๊ฐ์ฒด ๋ด๋ถ์์ ์ง์ ํธ์ถํ๋ ๋์ , ์ธ๋ถ(์คํ๋ง IoC ์ปจํ ์ด๋๋ฅผ ์ด์ฉํจ)์์ ๊ฐ์ฒด๋ฅผ ์์ฑํด์ ๋ฃ์ด์ฃผ๋ ๋ฐฉ์ ์ฝ๊ฒ ๋งํ์๋ฉด ์ฉ๋์ ๋ง๊ฒ ํ์ํ ๊ฐ์ฒด๋ฅผ ๊ทธ๋ฅ ๊ฐ์ ธ๋ค ์ฌ์ฉํ๋ ๊ฒ์ด๋ค. ์ด ๊ฐ์ฒด๋ค์ด ์ด๋ป๊ฒ ๋ง๋ค์ด์ก๋์ง๋ ์ ํ์๊ฐ ์๋ ๊ฒ์ด๋ค. ์๋ฅผ ๋ค์ด ์ฅ๋๊ฐ์ ๋ฐฐํฐ๋ฆฌ๋ฅผ ๋ฐ๊พธ๋ ๊ฒ๊ณผ ๊ฐ์ด ํ์ํ ๋ ๊ฐ์ ธ๋ค๊ฐ ์ฌ์ฉํ๋ ๊ฒ์ด๋ค. ์ด๋ก ์ธํด ์ฝ๋๊ฐ ๊ฐ๊ฒฐํด์ง๋ฉด์ ๊ฐ์ฒด๊ฐ์ ๊ฒฐํฉ๋๋ฅผ ๋ฎ์ถฐ์ฃผ๋ฉฐ ๋์์ ํ์ฅ์ฑ์ ์ฆ๊ฐ ์์ผ์ค๋ค.
๊ทธ๋ผ ์ด๋ ๋๋ ์๋ฌธ์ ์ ์คํ๋ง์์๋ ๋ชจ๋ ๊ฐ์ฒด๋ฅผ ์ฃผ์ ํ ์ ์๋๊ฒ์ธ์ง, ์ธ์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋์ง, ๊ทธ๋ฆฌ๊ณ ์ด๋์ ์์ฑ๋ ๊ฐ์ฒด๋ค์ด ์กด์ฌํ๋ ๊ฒ์ด๋ค. ๊ทธ๋ฆฌ๊ณ ์ด๋ป๊ฒ ์ด ์์ฑ๋ ๊ฐ์ฒด๋ค์ด ์ฃผ์ ์ด ๋๋ ๊ฒ์ด๋ค.
: ์ผ๋จ ๊ฒฐ๋ก ์ ์๋๋ค. ์คํ๋ง์์๋ bean ์ผ๋ก ๋ฑ๋ก๋ ๊ฐ์ฒด์ด๊ฑฐ๋ ์คํ๋ง์ด ์ค์บํ ๊ฐ์ฒด๋ค๋ง ์์กด์ฑ ์ฃผ์ ์ด ๊ฐ๋ฅ ํ๋ค๋ ๊ฒ์ด๋ค. ์ฌ๊ธฐ์ bean ์ ์คํ๋ง์ด ๊ด๋ฆฌํ๋ ๊ฐ์ฒด์ด๋ค.
bean์ผ๋ก ๋ฑ๋ก๋์ง ์์ ๊ฐ์ฒด๋public class Car1 { private BatteryA batteryA = new BatteryA(100, "Energizer"); }
์ด๋ ๊ฒ ๋ค์ "new ~~" ๋ฅผ ์์ฑํด์ ํด๋์ค ๋ด๋ถ์์ ์ง์ ์์ฑํ์ฌ ๊ด๋ฆฌ๋ฅผ ํ์์ง๋ง,
๋ฐ๋ฉด์, bean์ผ๋ก ๋ฑ๋ก๋๊ฑฐ๋ ์คํ๋ง์ด ์ค์บํ ๊ฐ์ฒด๋public class Car1 { private BatteryA batteryA; }
๋ด๋ถ์์ ์์ฑ๋ ํ์์์ด ๊ฐ๋จํ๊ฒ ์ฃผ์ ํด์ ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋ค๋ ๊ฒ์ด๋ค!
๊ทธ๋ผ ์ธ์ ์คํ๋ง์ ๊ฐ์ฒด๋ค์ ์์ฑํ๋ ๊ฒ์ผ๊น?
: ๊ฐ๋จํ๊ฒ๋ ์คํ๋ง ํ๋ก์ ํธ๊ฐ ์์๋ ๋, ์คํ๋ง์ด bean ๊ฐ์ฒด๋ ์ด๋ ธํ ์ด์ ์ด ๋ถ์ ๊ฐ์ฒด๋ค์ ์ค์บํ์ฌ์ ์์ฑํ๋ค. ์กฐ๊ธ ๋ ๊น๊ฒ ํ๊ณ ๋ค๋ฉด Bean Application Context๊ฐ ์์ ๋ ๋ ์ด๋ค. Application Context๊ด๋ จํด์๋ ๋์ค์ ์กฐ๊ธ ๋ ๊น๊ฒ ํ๋ณด์. ์ผ๋จ์ ์คํ๋ง ํ๋ก์ ํธ๊ฐ ์์๋ ๋ ์์ฑ๋๋ ๊ฒ์ด๋ผ๊ณ ์๊ณ ์์ผ๋ฉด ๋๊ฒ ๋ค.
๊ทธ๋ผ ์ด๋ป๊ฒ ์คํ๋ง์ bean ๊ฐ์ฒด๋ค์ ์ฃผ์ ํด์ค๊น?
: ์คํ๋ง์๋ bean ๊ฐ์ฒด๋ค์ด ๋ด๊ฒจ์ ธ ์๋ IoC(Inversion of Control) ์ปจํ ์ด๋๋ผ๋ ๊ฒ์ด ์๋ค. ์์ฑ๋ bean ๊ฐ์ฒด๋ค์ ์คํ๋ง IoC ์ปจํ ์ด๋ ๋ด๊ฒจ์ ธ ์๋ ๊ฒ์ด๋ค. ๊ทธ ํ, ์ฌ๊ธฐ์ ์๋ bean ๊ฐ์ฒด๋ค์ ํ์ํ ๊ฐ์ฒด๋ค์ ์ฃผ์ ์ ํด์ฃผ๋ ๊ฒ์ด๋ค.
๊ทธ๋ผ ์ฌ๊ธฐ์ ๋ง์ง๋ง ์๋ฌธ์ ์ ์ด๋ป๊ฒ bean ๊ฐ์ฒด๋ค์ ์ฃผ์ ์ ํด์ฃผ๋ ๊ฒ์ด๋ค.
: ์ด์ ์ฌ๊ธฐ์ ์์์ ์ธ๊ธํ DI ๋ผ๋ ๊ฐ๋ ์ด ๋์จ๋ค.
์คํ๋ง์์ DI๋ฅผ ํ๋ ๋ฐฉ๋ฒ์ ์ด 3๊ฐ์ง๊ฐ ์๋ค. ์์ฑ์ ์ฃผ์ , setter/์์ ์ ์ฃผ์ , ๊ทธ๋ฆฌ๊ณ ํ๋ ์ฃผ์ ์ด ์๋ค.
- ์์ฑ์ ์ฃผ์ (Constructor Injection)
= ํด๋น ๊ฐ์ฒด์ ์ฃผ์ ๋์ด์ผ ํ๋ ๊ฐ์ฒด๋ฅผ ํด๋น ๊ฐ์ฒด ์์ฑ์ ํ๋ผ๋ฏธํฐ๋ก ์ ํด๋๋ค. ๊ทธ๋ฌ๋ฉด ํด๋น ๊ฐ์ฒด๊ฐ ์์ฑ๋ ๋, ์คํ๋ง์ด ํด๋น ๊ฐ์ฒด ์์ฑ์์ ํ๋ผ๋ฏธํฐ๋ฅผ ํ์ธํด์ ์คํ๋ง IoC ์ปจํ ์ด๋์ bean ๊ฐ์ฒด๋ฅผ ํ์ธํ๊ณ ์ฃผ์ ํด์ค๋ค. ์ด ๋ฐฉ๋ฒ์ ๊ฐ์ฅ ๋ง์ด ์ฐ์ด๋ ๋ฐฉ๋ฒ์ผ๋ก์จ ์ฃผ์ ๋ฐ์ ๊ฐ์ฒด๊ฐ ๋ณํ์ง ์๊ฑฐ๋, ๋ฐ๋์ ๊ฐ์ฒด์ ์ฃผ์ ์ด ํ์ํ ๊ฒฝ์ฐ์ ์ฌ์ฉํ ์ ์๋ค. ๋ํ Spring ํ๋ ์์ํฌ์์๋ ์์ฑ์ ์ฃผ์ ์ ์ ๊ทน ์ง์ํ๊ณ ์๊ธฐ ๋๋ฌธ์, ์์ฑ์๊ฐ 1๊ฐ๋ง ์์ ๊ฒฝ์ฐ์ @Autowired๋ฅผ ์๋ตํด๋ ์ฃผ์ ์ด ๊ฐ๋ฅํ๋๋ก ํธ์์ฑ์ ์ ๊ณตํ๊ณ ์๋ค. ๊ทธ๋ฆฌ๊ณ ์คํ๋ง ๊ณต์๋ฌธ์๋ ์์ฑ์ ์ฃผ์ ์ฌ์ฉ์ ๊ถ์ฅํ๋ค.public class Car1 { private BatteryA batteryA; @Autowired //์์ฑ์๊ฐ ํ๋ ์ผ๋๋ ์๋ต ๊ฐ๋ฅ public Car1(BatteryA batteryA) { this.batteryA = batteryA; } }
- ์์ ์ ์ฃผ์ (Setter ์ฃผ์ , Setter Injection)
= ํด๋น ๊ฐ์ฒด์ ์ ํ์ ์ผ๋ก ์ฃผ์ ๋๋ ๊ฐ์ฒด๋ฅผ setter ๋ฉ์๋์ ํ๋ผ๋ฏธํฐ๋ก ์ ํด๋๋ค. ๊ทธ ํ, ์ํฉ์ ๋ง๊ฒ setter ๋ฉ์๋๋ฅผ ํธ์ถํ๋ฉด ์คํ๋ง์ด ํ๋ผ๋ฏธํฐ๋ฅผ ํ์ธํด์ ์คํ๋ง IoC ์ปจํ ์ด๋์ bean ๊ฐ์ฒด๋ฅผ ํ์ธํ๊ณ ์ฃผ์ ํด์ค๋ค. Setter ์ฃผ์ ์ ์์ฑ์ ์ฃผ์ ๊ณผ ๋ค๋ฅด๊ฒ ์ฃผ์ ๋ฐ๋ ๊ฐ์ฒด๊ฐ ๋ณ๊ฒฝ๋ ๊ฐ๋ฅ์ฑ์ด ์๋ ๊ฒฝ์ฐ์ ์ฌ์ฉํ๋ค.public class Car1 { private BatteryA batteryA; @Autowired //์๋ต ๊ฐ๋ฅํ๋ค. public void setBatteryA(BatteryA batteryA) { this.batteryA = batteryA; } }
- ํ๋ ์ฃผ์ (Field Injection)
= ํด๋น ๊ฐ์ฒด์ ์ฃผ์ ๋์ด์ผํ๋ ๊ฐ์ฒด๋ฅผ ์ ์ธ ํํ @Autowired ์ด๋ ธํ ์ด์ ์ ๋ถ์ธ๋ค. ํด๋น ๊ฐ์ฒด๊ฐ ์์ฑ๋ ๋, ์คํ๋ง์ด @Autowired ์ด๋ ธํ ์ด์ ์ด ๋ถ์ ํ๋๋ฅผ ํ์ธ ํ ํ ์คํ๋ง IoC ์ปจํ ์ด๋์ bean ๊ฐ์ฒด๋ฅผ ํ์ธํ๊ณ ์ฃผ์ ํด์ค๋ค. ์ด ์ฃผ์ ์ ์ฝ๋๊ฐ ๊ฐ๊ฒฐํด์ ธ์ ๊ณผ๊ฑฐ์ ์๋นํ ๋ง์ด ์ด์ฉ๋์๋ ์ฃผ์ ๋ฐฉ๋ฒ์ด๋ค. ํ์ง๋ง ํ๋ ์ฃผ์ ์ ์ธ๋ถ์์ ์ ๊ทผ์ด ๋ถ๊ฐ๋ฅํ๋ค๋ ๋จ์ ์ด ์กด์ฌํ๋๋ฐ, ํ ์คํธ ์ฝ๋์ ์ค์์ฑ์ด ๋ถ๊ฐ๋จ์ ๋ฐ๋ผ ํ๋์ ๊ฐ์ฒด๋ฅผ ์์ ํ ์ ์๋ ํ๋ ์ฃผ์ ์ ๊ฑฐ์ ์ฌ์ฉ๋์ง ์๊ฒ ๋์๋ค. ๋ํ ํ๋ ์ฃผ์ ์ ๋ฐ๋์ DI ํ๋ ์์ํฌ๊ฐ ์กด์ฌํด์ผ ํ๋ฏ๋ก ๋ฐ๋์ ์ฌ์ฉ์ ์ง์ํด์ผ ํ๋ค.public class Car1 { @Autowired private BatteryA batteryA; }
์์์ ์ธ๊ธํ๋ฏ์ด, ์คํ๋ง ๊ณต์ ๋ฌธ์๋ ์์ฑ์ ์ฃผ์ ์ฌ์ฉ์ ๊ถ์ฅํ๋ค. ๊ณต์ ๋ฌธ์๋ ์ด๋ ๊ฒ ์์ฑ ๋์ด์๋ค
"Spring ํ์ ์ผ๋ฐ์ ์ผ๋ก ์์ฑ์ ์ฃผ์ ์ ์ง์งํฉ๋๋ค. ์ด๋ ์ ํ๋ฆฌ์ผ์ด์ ๊ตฌ์ฑ ์์๋ฅผ ๋ถ๋ณ ๊ฐ์ฒด๋ก ๊ตฌํํ๊ณ ํ์ํ ์์กด ๊ฐ์ฒด๊ฐ null์ด ์๋์ ๋ณด์ฅํ๊ธฐ ๋๋ฌธ์ ๋๋ค. ๋ํ ์์ฑ์๊ฐ ์ฃผ์ ํ ๊ตฌ์ฑ ์์๋ ํญ์ ์์ ํ ์ด๊ธฐํ๋ ์ํ์์ ํด๋ผ์ด์ธํธ(ํธ์ถ) ์ฝ๋๋ก ๋ฐํ๋ฉ๋๋ค."
- ์์ฑ ๋ ๋ ์ฃผ์ ์ด ๋๋ค.
ํด๋น ๊ฐ์ฒด๊ฐ ์์ฑ ๋ ๋ ๋ถํฐ ํ์ํ ๊ฐ์ฒด๋ค์ด ์ฃผ์ ๋๋ค. ์ด๋ ์์ฑ์๊ฐ ํ์ํ ๋ชจ๋ ๊ฐ์ฒด๊ฐ ์ฃผ์ ๋์ง ์์ผ๋ฉด ํด๋น ๊ฐ์ฒด๊ฐ ์์ฑ๋์ง ์์ ๊ฒ์ด๋ผ๊ณ 100% ํ์ ํ ์ ์๋ค. ๋ํ ํ์ํ ๋ชจ๋ ๊ฐ์ฒด๊ฐ ์ฃผ์ ๋์๋์ง ํ์ธํ๊ธฐ ์ํ ๋ณ๋์ ์ฝ๋๋ฅผ ์์ฑํ ํ์๊ฐ ์์ผ๋ฏ๋ก ๋งค์ฐ ์ ์ฉํ๋ฏ๋ก ์ฝ๋ ๋ณต์ก์ฑ์ ๋จ์ํํ๋ค.public class Car1 { private BatteryA batteryA; private BatteryB batteryB; public Car1(BatteryA batteryA, BatteryB batteryB) { this.batteryA = batteryA; this.batteryB = batteryB; } }
์์ ์ฝ๋์์ batteryA๋ bean ๊ฐ์ฒด์ด๊ณ batteryB๋ bean ๊ฐ์ฒด๊ฐ ์๋๋ค. ์ด๋, Car1 ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ค ํ ๋, ์๋ฌ๊ฐ ๋๋ค. ์ด๋, ๊ฐ์ฒด๊ฐ ์์ฑ์ด ๋ ๋ ์์ฑ์ ํ๋ผ๋ฏธํฐ์ ๊ฐ์ฒด๋ค์ด ์ฃผ์ ์ด ๋๋๋ฐ batteryB๋ bean ๊ฐ์ฒด๊ฐ ์๋๊ธฐ ๋๋ฌธ์ ๋๋ ์๋ฌ์ด๋ค.
- ์ฝ๋ ๋์ ์๋ณ
์ฃผ์ ๋์ด์ผํ๋ ๋ชจ๋ ๊ฐ์ฒด๋ค์ ์ฝ๊ฒ ์ ์ ์๋ค. ์ด๋ก ์ธํด, ํด๋น ๊ฐ์ฒด๊ฐ ๋ง์ ๋ค๋ฅธ ๊ฐ์ฒด๋ค์๊ฒ ์์กด ํ๋์ง ์ ์ ์๋ค. ๋ง์ฝ ์์กด ํ๋ ๊ฐ์ฒด๊ฐ ๋ง๋ค๋ฉด ํด๋น ๊ฐ์ฒด๊ฐ ๋ง์ ์ฑ ์๊ฐ์ ๊ฐ์ง๊ณ ์๋ ๊ฒ์ ๋ปํ๋ฉด์ ์ด๋ ๋์ ์ฝ๋ ๋์๋ผ๊ณ ํ ์ ์๋ค.public class Car1 { private BatteryA batteryA; private BatteryB batteryB; private Window window; private Tire tire; private Wheel wheel; private Engine engine; public Car1(BatteryA batteryA, BatteryB batteryB, Window window, Tire tire, Wheel wheel, Engine engine) { this.batteryA = batteryA; this.batteryB = batteryB; this.window = window; this.tire = tire; this.wheel = wheel; this.engine = engine; } }
์์ ์ฝ๋ ์ฒ๋ผ ์์ฑ์์์ ์ผ๋ง๋ ๋ง์ ๊ฐ์ฒด๋ค์ด ์ฃผ์ ์ด ๋์ด์ ธ์ผํ๋์ง ์ ์ ์๋ค.
- ํ ์คํธ ์ฝ๋ ์์ฑ ์ฉ์ด
์์ฑ์ ์ฃผ์ ์ ํ์ํ ๊ฐ์ฒด๋ค์ ์์ฑ์์ ๋ช ์ํ์ฌ์ ํด๋น ๊ฐ์ฒด๋ฅผ ํ ์คํธํ ๋ ํ์ํ ์์กด ๊ฐ์ฒด๋ค์ Mockito๋ฅผ ์ฌ์ฉํด ์ฝ๊ฒ ๋ชจ์ ๊ตฌํ ํ ์ ์๋ค. ๋ํ, ์ด๋ ๋จ์ ํ ์คํธ์ ์ ์ด ๋ฐ ๊ฒฉ๋ฆฌ๋ฅผ ๊ฐ์ ํด์ค๋ค.public class Car1 { private BatteryA batteryA; public Car1(BatteryA batteryA) { this.batteryA = batteryA; } public String CarHasBattery(){ return "BROOM BROOM"; } }
์๋ฅผ ๋ค์ด ์๊ฐ Car1์ ๋ํ ์ฝ๋์ด๋ฉด,
class Car1Test { @Mock BatteryA batteryA; @Test void CarTest(){ Car1 car1 = new Car1(batteryA); assertEquals("BROOM BROOM", car1.CarHasBattery()); //Success } }
์์ ์ฒ๋ผ ํ ์คํธ ์ฝ๋๋ฅผ ์ฃผ์ ๋์ด์ผํ๋ ๊ฐ์ฒด๋ฅผ Mock์ผ๋ก ์ฝ๊ฒ ์์ฑ ํ ์์ฑ ํ ์ ์๋ค.
- ๋ถ๋ณ์ฑ
์์ฑ์ ์ฃผ์ ์ผ๋ก ์ฃผ์ ๋ฐ์ ๊ฐ์ฒด๊ฐ ๋ถ๋ณํ๋ค๋ ์ฅ์ ์ ๊ฐ์ง๊ณ ์๋ค. ์ด๋, NullPointerException์ ๋ฐฉ์ง ํ ์ ์๋ค. ๋ํ, ๋ด๋ถ ์ํ ๋ณํ๋ก ์ธํ ๋ฒ๊ทธ์ ๋ ์ทจ์ฝํ๋ค๋ ๊ฒ์ด๋ค.
๊ฐ์น ์๋ ์ ๋ณด ๊ณต์ ํด์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค.