[Spring] ๐Ÿ“š IoC vs DI vs DIP

ํ—Œ์น˜ยท2022๋…„ 10์›” 5์ผ
6

Spring

๋ชฉ๋ก ๋ณด๊ธฐ
8/13

1. IoC(Inversion of Control) : ์ œ์–ด์˜ ์—ญ์ „

โœจย ๊ฐœ๋…

๐Ÿ“ข Spring์—๋งŒ ์ ์šฉ๋˜๋Š” ๊ฐœ๋…์ด ์•„๋‹ˆ๋‹ค!

Michael Mattson์˜ 1996๋…„ ๋…ผ๋ฌธย Object-Oriented Frameworks: A survey of methodological issues์—์„œ ์ฒ˜์Œ ๋“ฑ์žฅํ•œ ๊ฐœ๋….

์ œ์–ด์˜ ์—ญ์ „, ์ฆ‰ IoC๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ๊ตฌํ˜„ํ•œ ํ”„๋กœ๊ทธ๋žจ์ด ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ย ํ๋ฆ„ ์ œ์–ด๋ฅผ ๋ฐ›๋Š” ๋””์ž์ธ ์›์น™์„ ๋งํ•œ๋‹ค.

- ์œ„ํ‚ค๋ฐฑ๊ณผ

ํ˜ธ์ถœ ๋ฐฉํ–ฅ

  • ์ „ํ†ต์ ์ธ ํ”„๋กœ๊ทธ๋ž˜๋ฐ : ๊ฐœ๋ฐœ์ž์˜ ๊ตฌํ˜„ โ†’ ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ฝ”๋“œ
  • IoC ๊ตฌ์กฐ : ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ฝ”๋“œ โ†’ ๊ฐœ๋ฐœ์ž์˜ ๊ตฌํ˜„

์ด๋Ÿฌํ•œ IoC ๊ตฌ์กฐ์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ”„๋ ˆ์ž„์›Œํฌ๋ผ ๋ถ€๋ฅธ๋‹ค!

โœจย โ€œํ• ๋ฆฌ์šฐ๋“œ ์›์น™โ€ ์ด๋ผ๊ณ ๋„ ๋ถˆ๋ฆฐ๋‹ค!

"์šฐ๋ฆฌ์—๊ฒŒ ์ „ํ™”ํ•˜์ง€ ๋งˆ์„ธ์š”. ์šฐ๋ฆฌ๊ฐ€ ๋‹น์‹ ์—๊ฒŒ ์—ฐ๋ฝํ• ๊ฒŒ์š”.โ€

Don't call us, we'll call you๐Ÿ˜Ž

โ€œGoF์˜ ๋””์ž์ธ ํŒจํ„ดโ€์˜ ํ…œํ”Œ๋ฆฟ ๋ฉ”์†Œ๋“œ ํŒจํ„ด ์ฑ•ํ„ฐ์—์„œ ๋“ฑ์žฅํ•˜๋Š” ๋น„์œ 

  • ๋ฝ‘๊ธฐ ์–ด๋ ค์šด ์‚ฌ์›์—๊ฒŒ ๋‚˜์ค‘์— ์—ฐ๋ฝํ•  ํ…Œ๋‹ˆ ์ž๊พธ ์ „ํ™”ํ•˜์ง€ ๋ง๋ผ๋Š” ํšŒ์‚ฌ ์ธก์˜ ๋ง๋กœ ์ž์ฃผ ์“ฐ์ธ๋‹ค.
  • 1960๋…„๋Œ€ ๋ฏธ๊ตญ์—์„œ ๋ฉด์ ‘๊ด€๋“ค์ด ์“ฐ๊ธฐ ์‹œ์ž‘ํ•œ ๋ง์ธ๋ฐ, ๋‚˜์ค‘์— ๊ทน์žฅ์—์„œ ๋ฐฐ์šฐ๋“ค์˜ ์˜ค๋””์…˜์„ ๋ณด๊ณ  ๊ฑฐ์ ˆํ•  ๋•Œ ๋” ๋งŽ์ด ์จ ์œ ๋ช…ํ•ด์กŒ๋‹ค.
  • ์—ฌ๊ธฐ์„œ ๋ฐฐ์šฐ๋Š” ๊ตฌํ˜„ ๋ชจ๋“ˆ, ์˜ํ™”์‚ฌ๋Š” ํ”„๋ ˆ์ž„์›Œํฌ๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

From. ํ…œํ”Œ๋ฆฟ ๋ฉ”์†Œ๋“œ ํŒจํ„ด๐Ÿ“ฅ

ํ๋ฆ„์ œ์–ด์˜ ์ฃผ์ฒด๋Š” ๋ถ€๋ชจ ํด๋ž˜์Šค์ธ AbstractClass์ด๋‹ค.

  • ๋ถ€๋ชจ ํด๋ž˜์Šค(= ์™ธ๋ถ€ ํ”„๋กœ๊ทธ๋žจ, ์ƒ์œ„ํด๋ž˜์Šค, ์ถ”์ƒํด๋ž˜์Šค, AbstractClass, ํ”„๋ ˆ์ž„์›Œํฌ)๋Š”
  • ์„œ๋ธŒ ํด๋ž˜์Šค(= ๋ชจ๋“ˆ, ํ•˜์œ„ํด๋ž˜์Šค, ๊ตฌ์ฒดํด๋ž˜์Šค, ConcreteClass, ํด๋ผ์ด์–ธํŠธ) ์—ฐ์‚ฐ์„ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์ง€๋งŒ,
  • ๋ฐ˜๋Œ€๋ฐฉํ–ฅ์œผ๋กœ ํ˜ธ์ถœํ•  ์ˆ˜๋Š” ์—†๋‹ค!

์ด์™ธ์—๋„

์ „๋žต ํŒจํ„ด, ์„œ๋น„์Šค ๋กœ์ผ€์ดํ„ฐ ํŒจํ„ด, ํŒฉํ† ๋ฆฌ ํŒจํ„ด, ์˜์กด๊ด€๊ณ„ ์ฃผ์ž…(DI) ,์˜์กด๊ด€๊ณ„ ๊ฒ€์ƒ‰(DL)

๋“ฑ์˜ ๋ฐฉ๋ฒ•์œผ๋กœ IoC๋ฅผ ๋‹ฌ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค!

โœจย ํ•ด๊ฒฐ

์˜์กด์„ฑ ๋ถ€ํŒจ(dependency rot)๐Ÿ˜ฑ

์˜์กด์„ฑ ๋ถ€ํŒจ : ๊ณ ์ˆ˜์ค€ ๊ตฌ์„ฑ์š”์†Œ๊ฐ€ ์ €์ˆ˜์ค€ ๊ตฌ์„ฑ์š”์†Œ์— ์˜์กดํ•˜๊ณ , ๊ทธ ์ €์ˆ˜์ค€ ๊ตฌ์„ฑ์š”์†Œ๋Š” ๋‹ค์‹œ ๊ณ ์ˆ˜์ค€ ๊ตฌ์„ฑ์š”์†Œ์— ์˜์กดํ•˜๊ณ , ๊ทธ ๊ณ ์ˆ˜์ค€ ๊ตฌ์„ฑ์š”์†Œ๋Š” ๋‹ค์‹œ ๋˜ ๋‹ค๋ฅธ ๊ตฌ์„ฑ์š”์†Œ์— ์˜์กดํ•˜๊ณ , ๊ทธ ๋‹ค๋ฅธ ๊ตฌ์„ฑ์š”์†Œ๋Š” ๋˜ ์ €์ˆ˜์ค€ ๊ตฌ์„ฑ์š”์†Œ์— ์˜์กดํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ์‹์œผ๋กœ ์˜์กด์„ฑ์ด ๋ณต์žกํ•˜๊ฒŒ ๊ผฌ์—ฌ์žˆ๋Š” ๊ฒƒ

  • Head First Design Patterns

๊ฒฐํ•ฉ๋„๐Ÿ”—

  • ์ž‘์—…์˜ ๊ตฌํ˜„๋ฐฉ์‹(๋ชจ๋“ˆ)๊ณผ ์ž‘์—…์˜ ์ˆ˜ํ–‰(์™ธ๋ถ€ ํ”„๋กœ๊ทธ๋žจ) ์ž์ฒด๋ฅผ ๋ถ„๋ฆฌํ•œ๋‹ค. ๊ทธ๋กœ์จ ๊ฒฐํ•ฉ๋„๋ฅผ ์ค„์ธ๋‹ค.
  • ๋”ฐ๋ผ์„œ ๋ชจ๋“ˆ์„ ๋ณ€๊ฒฝํ•ด๋„ ๋‹ค๋ฅธ ์‹œ์Šคํ…œ์— ๋ถ€์ž‘์šฉ์„ ์ผ์œผํ‚ค์ง€ ์•Š๋Š”๋‹ค.

2. DIP(Dependency Inversion principle) : ์˜์กด์„ฑ ์—ญ์ „ ์›์น™

โœจย ๊ฐœ๋…

Robert Martinย (Uncle BoB)์— ์˜ํ•ด ์†Œ๊ฐœ๋œย SOLIDย ์›์น™ ์ค‘ ํ•˜๋‚˜.

ํ•˜์œ„ ๋ ˆ๋ฒจ ๋ชจ๋“ˆ์˜ ๋ณ€๊ฒฝ์ด ์ƒ์œ„ ๋ ˆ๋ฒจ ๋ชจ๋“ˆ๊นŒ์ง€ ์ „ํŒŒ๋˜๋Š” ๊ตฌ์กฐ์  ๋ฌธ์ œ์—์„œ ๋ฐœ์ƒํ•˜๋Š” ์œ„๊ณ„๊ด€๊ณ„๋ฅผ ๋Š๊ธฐ ์œ„ํ•œ ์›์น™์ด๋‹ค.

์•„๋ž˜ 2๊ฐ€์ง€ ์›์น™์„ ๋”ฐ๋ฅธ๋‹ค.

  • ์ƒ์œ„ ๋ชจ๋“ˆ์€ ํ•˜์œ„ ๋ชจ๋“ˆ์— ์ข…์†๋˜๋ฉด ์•ˆ๋˜๊ณ  ๋‘˜ ๋‹คย ์ถ”์ƒํ™”์— ์˜์กดํ•ด์•ผ ํ•œ๋‹ค.
  • ์ถ”์ƒํ™”๋Š” ์„ธ๋ถ€์‚ฌํ•ญ์— ์˜์กดํ•˜๋ฉด ์•ˆ ๋˜๊ณ , ์„ธ๋ถ€์‚ฌํ•ญ์€ ์ถ”์ƒํ™”์— ์˜์กดํ•ด์•ผ ํ•œ๋‹ค.

โœจย ์žฅ์ 

  • ๋ณ€ํ™”ํ•˜์ง€ ์•Š๋Š” ์ถ”์ƒํ™”์— ์˜์กดํ•จ์œผ๋กœ์จ, ํ™•์žฅ์— ์œ ์—ฐํ•˜๊ณ  ๋ณ€๊ฒฝ์— ํ์‡„์ ์ธ ์„ค๊ณ„๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.์ฆ‰, OCP๋ฅผ ์ง€ํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.

3. DI(Dependency Injection) : ์˜์กด๊ด€๊ณ„ ์ฃผ์ž…

โœจย ๊ฐœ๋…

๋งˆํ‹ด ํŒŒ์šธ๋Ÿฌ๊ฐ€ ์ฐฝ์‹œํ•œ ๊ฐœ๋….

ํ•˜๋‚˜์˜ ๊ฐ์ฒด๊ฐ€ ๋‹ค๋ฅธ ๊ฐ์ฒด์˜ ์˜์กด์„ฑ์„ ์ œ๊ณตํ•˜๋Š” ํ…Œํฌ๋‹‰์ด๋‹ค.

  • "์˜์กด๊ด€๊ณ„"๋Š” ์˜ˆ๋ฅผ ๋“ค์–ด ๊ตฌํ˜„๋ฐฉ์‹(๋ชจ๋“ˆ)์ด๋‹ค. ํด๋ผ์ด์–ธํŠธ๋Š” ๋ชจ๋“ˆ์„ ์‹คํ–‰ํ•œ๋‹ค.
  • "์ฃผ์ž…"์€ ์˜์กด๊ด€๊ณ„(๋ชจ๋“ˆ)์„ ํด๋ผ์ด์–ธํŠธ๋กœ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.

ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์„œ๋น„์Šค(๋ชจ๋“ˆ)๋ฅผ ์ง์ ‘ ๊ตฌ์ถ•ํ•˜๊ฑฐ๋‚˜ ์ฐพ๋Š” ๋Œ€์‹ , ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์„œ๋น„์Šค(๋ชจ๋“ˆ)๋ฅผ ์ „๋‹ฌ(์ฃผ์ž…)ํ•˜๋Š” ๊ฒƒ์ด ํŒจํ„ด์˜ ๊ธฐ๋ณธ ์š”๊ฑด์ด๋‹ค.

-์œ„ํ‚ค๋ฐฑ๊ณผ

โœจย ์žฅ์ 

  • ๊ฐ์ฒด์˜ ์ƒ์„ฑ๊ณผ ์‚ฌ์šฉ์˜ ๊ด€์‹ฌ์„ ๋ถ„๋ฆฌํ•œ๋‹ค!
  • ๊ทธ๋กœ์จ ๊ฐ€๋…์„ฑ๊ณผ ์ฝ”๋“œ ์žฌ์‚ฌ์šฉ๋ฅ ์„ ๋†’ํ˜€์ค€๋‹ค.
  • ๋ชจ๋“ˆ์˜ ํ…Œ์ŠคํŠธ๊ฐ€ ์‰ฌ์›Œ์ง„๋‹ค.

โœจย ์˜์กด๊ด€๊ณ„ ์ฃผ์ž…

'Dependency Injection'์€ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์šฐ๋ฆฌ๋ง๋กœ ๋ฒˆ์—ญ๋ผ์„œ ์‚ฌ์šฉ๋œ๋‹ค. ๊ทธ์ค‘์—์„œ ๊ฐ€์žฅ ํ”ํžˆ ์‚ฌ์šฉ๋˜๋Š” ์šฉ์–ด๊ฐ€ ์˜์กด์„ฑ ์ฃผ์ž…์ด๋‹ค. ํ•˜์ง€๋งŒ ์˜์กด์„ฑ์ด๋ผ๋Š” ๋ง์€ DI์˜ ์˜๋ฏธ๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์ž˜ ๋“œ๋Ÿฌ๋‚ด์ฃผ์ง€ ๋ชปํ•œ๋‹ค.

(โ€ฆ) ์—„๋ฐ€ํžˆ ๋งํ•ด์„œ ์˜ค๋ธŒ์ ํŠธ๋Š” ๋‹ค๋ฅธ ์˜ค๋ธŒ์ ํŠธ์— ์ฃผ์ž…ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒŒ ์•„๋‹ˆ๋‹ค. ์˜ค๋ธŒ์ ํŠธ์˜ ๋ ˆํผ๋Ÿฐ์Šค๊ฐ€ ์ „๋‹ฌ๋  ๋ฟ์ด๋‹ค.

DI๋Š” ์˜ค๋ธŒ์ ํŠธ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ์™ธ๋ถ€๋กœ๋ถ€ํ„ฐ ์ œ๊ณต(์ฃผ์ž…)๋ฐ›๊ณ  ์ด๋ฅผ ํ†ตํ•ด ์—ฌํƒ€ ์˜ค๋ธŒ์ ํŠธ์™€ ๋‹ค์ด๋‚ด๋ฏนํ•˜๊ฒŒ ์˜์กด๊ด€๊ณ„๊ฐ€ ๋งŒ๋“ค์–ด์ง€๋Š” ๊ฒƒ์ด ํ•ต์‹ฌ์ด๋‹ค. ์šฉ์–ด๋Š” ๋™์ž‘๋ฐฉ์‹(๋ฉ”์ปค๋‹ˆ์ฆ˜)๋ณด๋‹ค๋Š” ์˜๋„๋ฅผ ๊ฐ€์ง€๊ณ  ์ด๋ฆ„์„ ์ง“๋Š” ๊ฒƒ์ด ์ข‹๋‹ค. ๊ทธ๋Ÿฐ ๋ฉด์—์„œ ์˜์กด๊ด€๊ณ„ ์ฃผ์ž…์ด๋ผ๋Š” ๋ฒˆ์—ญ์ด ์ ์ ˆํ•  ๋“ฏ์‹ถ๊ณ , ์ด ์ฑ…์—์„œ๋Š” ์ด๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

  • ํ† ๋น„์˜ ์Šคํ”„๋ง 1.7.2 112์ชฝ

4. IoC, DI, DIP ์ ์šฉ ์˜ˆ์‹œ

public interface Person {
  String study();
  String sleep();
}

public class Summer implements Person {
  @Override
  public String study() {
    return "์จ๋จธ๋Š” ์„ ๋ฆ‰์—์„œ ๊ณต๋ถ€ํ•œ๋‹ค.";
  }
  @Override
  public String sleep() {
    return "์จ๋จธ๋Š” ์ž”๋‹ค.";
  }
}

public class Philz implements Person {
  @Override
  public String study() {
    return "ํ•„์ฆˆ๋Š” ์ž ์‹ค์—์„œ ๊ณต๋ถ€ํ•œ๋‹ค.";
  }
  @Override
  public String sleep() {
    return "ํ•„์ฆˆ๋Š” ์ž”๋‹ค.";
  }
}
public class PersonService {

  private Person person;

  public PersonService(Person person) {
    this.person = person;
  }

  public String wootecoLife() {
    return person.study() + person.sleep();
  }
}
public class PersonServiceFactory {

  public static PersonService summerService() {
    return new PersonService(new Summer())
  }

  public static PersonService philzService() {
    return new PersonService(new Philz())
  }
}
public class Application {

  public static void main(String[] args) {
    PersonService summerService = PersonServiceFactory.summerService()
    summerService.wootecoLife();
    // "์จ๋จธ๋Š” ์„ ๋ฆ‰์—์„œ ๊ณต๋ถ€ํ•œ๋‹ค. ์จ๋จธ๋Š” ์ž”๋‹ค."
  }
}

๐Ÿ‘ย IoC๋ฅผ ๋งŒ์กฑํ•˜๋Š” ์„ค๊ณ„ ๊ตฌ์กฐ

  • ํ๋ฆ„์ œ์–ด์˜ ์ฃผ์ฒด๊ฐ€ ์ƒ์œ„ ํด๋ž˜์Šค์ธ PersonService์ด๋‹ค.
  • PersonService ๋Š” ๊ตฌํ˜„ ๋ชจ๋“ˆ์ธ Person์„ ํ˜ธ์ถœํ•ด wootecoLife()๋กœ์ง์„ ์ƒ์˜ํ•œ๋‹ค!
  • ๋ฐ˜๋ฉด Person์€ PersonService๋ฅผ ์•Œ์ง€ ๋ชปํ•œ๋‹ค.

๐Ÿ‘ย DIP๋ฅผ ๋งŒ์กฑํ•˜๋Š” ์„ค๊ณ„ ๊ตฌ์กฐ

  • ์ƒ์œ„๋ชจ๋“ˆ PersonService๋Š” ๊ตฌ์ฒด ํด๋ž˜์Šค Summer๊ฐ€ ์•„๋‹Œ, ์ถ”์ƒํ™”๋œ Person์— ์˜์กดํ•˜๊ณ  ์žˆ๋‹ค.
    • ์ฆ‰, ์ƒ์œ„๋ชจ๋“ˆ PersonService, ํ•˜์œ„๋ชจ๋“ˆ Summer ๋ชจ๋‘ ์ถ”์ƒํ™”๋œ Person์— ์˜์กดํ•˜๊ณ  ์žˆ๋‹ค!
  • ๋˜ํ•œ ์ถ”์ƒํ™”๋œ Person์€ Summer๋‚˜ Philz์— ์˜์กดํ•˜์ง€ ์•Š์œผ๋ฉฐ, Summer, Philz๋งŒ ์ถ”์ƒํ™”๋œ Person์— ์˜์กดํ•œ๋‹ค.

๐Ÿ‘ย DI๋ฅผ ๋งŒ์กฑํ•˜๋Š” ์„ค๊ณ„ ๊ตฌ์กฐ

  • ํด๋ผ์ด์–ธํŠธ PersonService๋Š” ์˜์กด๊ด€๊ณ„ Person์˜ ์–ด๋–ค ๊ฐ์ฒด๋ฅผ ์“ธ์ง€ ์ง์ ‘ new๋กœ ์ •์˜ํ•˜์ง€ ์•Š๋Š”๋‹ค.
  • ๊ฐ์ฒด ์ƒ์„ฑ ์ฑ…์ž„์„ ๋‹ด๋‹นํ•˜๋Š” PersonServiceFactory ์—์„œ ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•ด ์˜์กด๊ด€๊ณ„ Person์„ ์ฃผ์ž…๋ฐ›๋Š”๋‹ค!

4. Spring DI/IoC

โœจย IoC ์ปจํ…Œ์ด๋„ˆ(DI ์ปจํ…Œ์ด๋„ˆ)

IoC๋Š” ๋งค์šฐ ๋Š์Šจํ•˜๊ฒŒ ์ •์˜๋ผ์„œ ํญ๋„“๊ฒŒ ์‚ฌ์šฉ๋˜๋Š” ์šฉ์–ด์ด๋‹ค. ๋ช‡๋ช‡ ์‚ฌ๋žŒ์˜ ์ œ์•ˆ์œผ๋กœ ์Šคํ”„๋ง์ด ์ œ๊ณตํ•˜๋Š” IoC ๋ฐฉ์‹์„ ํ•ต์‹ฌ์„ ์งš์–ด์ฃผ๋Š” ์˜์กด๊ด€๊ณ„ ์ฃผ์ž…(Dependency Injection)์ด๋ผ๋Š”, ์ข€ ๋” ์˜๋„๊ฐ€ ๋ช…ํ™•ํžˆ ๋“œ๋Ÿฌ๋‚˜๋Š” ์ด๋ฆ„์„ ์‚ฌ์šฉํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ๋‹ค.

์Šคํ”„๋ง์ด ์—ฌํƒ€ ํ”„๋ ˆ์ž„์›Œํฌ์™€ ์ฐจ๋ณ„ํ™”๋ผ์„œ ์ œ๊ณตํ•ด์ฃผ๋Š” ๊ธฐ๋Šฅ์€ ์˜์กด๊ด€๊ณ„ ์ฃผ์ž…์ด๋ผ๋Š” ์ƒˆ๋กœ์šด ์šฉ์–ด๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ๋ถ„๋ช…ํ•˜๊ฒŒ ๋“œ๋Ÿฌ๋‚œ๋‹ค. ๊ทธ๋ž˜์„œ ์ดˆ๊ธฐ์—๋Š” ์ฃผ๋กœ IoC ์ปจํ…Œ์ด๋„ˆ๋ผ๊ณ  ๋ถˆ๋ฆฌ๋˜ ์Šคํ”„๋ง์ด ์ง€๊ธˆ์€ ์˜์กด๊ด€๊ณ„ ์ฃผ์ž… ์ปจํ…Œ์ด๋„ˆ ๋˜๋Š” ๊ทธ ์˜๋ฌธ์•ฝ์ž๋ฅผ ์จ์„œ DI ์ปจํ…Œ์ด๋„ˆ๋ผ๊ณ  ๋” ๋งŽ์ด ๋ถˆ๋ฆฌ๊ณ  ์žˆ๋‹ค.

  • ํ† ๋น„์˜ ์Šคํ”„๋ง 1์žฅ

์ •์˜

์ž๋™์œผ๋กœ ์˜์กด๊ด€๊ณ„๋ฅผ ์ฃผ์ž…ํ•ด์ฃผ๋Š” ์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ(์ปจํ…Œ์ด๋„ˆ)!

  • Bean์„ ์ƒ์„ฑํ•˜๊ณ ,
  • ์ƒ๋ช…์ฃผ๊ธฐ๋ฅผ ๊ด€๋ฆฌํ•˜๊ณ 
  • ์˜์กด๊ด€๊ณ„ ๊ฐ์ฒด๋ฅผ ๋‹ค๋ฅธ ๊ฐ์ฒด์—๊ฒŒ ์ฃผ์ž…ํ•ด์ฃผ๋Š” ์—ญํ• ์„ ๋‹ด๋‹นํ•œ๋‹ค.

๋ณดํ†ต ๋นˆ ํŒฉํ† ๋ฆฌ(BeanFactory)๋ฅผ ์ƒ์†ํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ปจํ…์ŠคํŠธ(ApplicationContext)๋ฅผ ์ฃผ๋กœ ์‚ฌ์šฉํ•œ๋‹ค.

(๋นˆ ํŒฉํ† ๋ฆฌ `=. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ปจํ…์ŠคํŠธ = DI ์ปจํ…Œ์ด๋„ˆ)

์—ญํ• 

  • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ปจํ…์ŠคํŠธ๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ IoC๋ฅผ ์ ์šฉํ•ด์„œ ๊ด€๋ฆฌํ•  โ€œ๋ชจ๋“  bean ๊ฐ์ฒด์— ๋Œ€ํ•œ ์ƒ์„ฑ๊ณผ ๊ด€๊ณ„ ์„ค์ •โ€์„ ๋‹ด๋‹นํ•œ๋‹ค.
  • ์œ„ ์˜ˆ์‹œ์˜ PersonServiceFactory ์˜ ์—ญํ• ์„ ํ•œ๋‹ค๊ณ  ๋ณด๋ฉด ๋œ๋‹ค.
  • ์ด DI ์ปจํ…Œ์ด๋„ˆ์—์„œ bean ๊ฐ์ฒด์— ๋Œ€ํ•œ ์ž๋™ DI ๊ฐ€ ์ด๋ค„์ง„๋‹ค!

์žฅ์ 

  • ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ POJO๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๊ด€๋ฆฌํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค.
  • ๊ฐœ๋ฐœ์ž๋Š” ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์— ์ง‘์ค‘ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๊ฐ์ฒด ์ƒ์„ฑ ์ฝ”๋“œ๊ฐ€ ์—†์œผ๋ฏ€๋กœ TDD๊ฐ€ ์šฉ์ดํ•˜๋‹ค.

โœจย Spring DI

@Component์ด๋‚˜ @Configuration ๋ฐ @Bean ์œผ๋กœ ๋นˆ์„ ๋“ฑ๋กํ•˜๋ฉด, ๋“ฑ๋ก๋œ ๋นˆ๋“ค ์‚ฌ์ด์˜ ์˜์กด๊ด€๊ณ„๊ฐ€ ์ž๋™์œผ๋กœ ์ฃผ์ž…๋œ๋‹ค.

๐Ÿ’ฌย ์ฃผ์ž… ๋ฐฉ๋ฒ• 1 : ์ƒ์„ฑ์ž ์ฃผ์ž…(Constructor Injection)

๋ณ„๋‹ค๋ฅธ ์–ด๋…ธํ…Œ์ด์…˜ ์—†์ด ๋งค๊ฐœ๋ณ€์ˆ˜ ์ƒ์„ฑ์ž๋งŒ ์—ด์–ด๋‘๋ฉด ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค. ์ฆ‰, @Autowired ์–ด๋…ธํ…Œ์ด์…˜์„ ์ƒ๋žตํ•ด๋„ ๋œ๋‹ค

@Component
public class Store {

    private Item item;

    public Store(Item item) {
        this.item = item;
    }
}

๐Ÿ’ฌย ์ฃผ์ž… ๋ฐฉ๋ฒ• 2 : ํ•„๋“œ ์ฃผ์ž…(Field Injection)

@Autowiredย ์ฃผ์„์œผ๋กœ ์˜์กด๊ด€๊ณ„๋ฅผ ์ฃผ์ž…ํ•  ์ˆ˜ ์žˆ๋‹ค .

@Component
public class Store {

    @Autowired
    private Item item;
}

๐Ÿ’ฌย ์ฃผ์ž… ๋ฐฉ๋ฒ• 3 : ์„ธํ„ฐ ์ฃผ์ž…(Setter Injection)

๋งŒ์•ฝ ํ•„์ˆ˜์ ์ธ ์˜์กด์„ฑ์„ ์ค˜์•ผํ•˜๋Š” ๊ณณ์—์„œ ์„ธํ„ฐ ์ฃผ์ž…์„ ์‚ฌ์šฉํ•˜๋ฉด

null์— ๋Œ€ํ•œ ๊ฒ€์ฆ ๋กœ์ง์„ ๋ชจ๋“  ํ•„๋“œ์— ์ถ”๊ฐ€ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

@Component
public class Store {

    private Item item;

    @Autowired
    public void setItem(Item item) {
        this.item = item;
    }
}

๐Ÿ’ฌย ์ƒ์„ฑ์ž ์ฃผ์ž…์„ ์“ฐ์ž!

1. ๋‹จ์ผ ์ฑ…์ž„์˜ ์›์น™

ํ•„๋“œ ์ฃผ์ž…์€ ์˜์กด์„ฑ ์ฃผ์ž…์ด ๋„ˆ๋ฌด ์‰ฌ์šฐ๋ฏ€๋กœ ๋ฌด๋ถ„๋ณ„ํ•œ ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ํ•˜๋‚˜์˜ ํด๋ž˜์Šค์—์„œ ์ง€๋‚˜์น˜๊ฒŒ ๋งŽ์€ ๊ธฐ๋Šฅ์„ ํ•˜๊ฒŒ ๋  ์ˆ˜ ์žˆ๋Š” ์—ฌ์ง€๊ฐ€ ์žˆ๊ณ , โ€˜๊ฐ์ฒด๋Š” ๊ทธ์— ๋งž๋Š” ๋™์ž‘๋งŒ ํ•œ๋‹คโ€™๋ผ๋Š” ๋‹จ์ผ ์ฑ…์ž„์˜ ์›์น™์ด ๊นจ์ง€๊ธฐ ์‰ฝ๋‹ค.

์ƒ์„ฑ์ž ์ฃผ์ž…์„ ์‚ฌ์šฉํ•˜๋ฉด ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•ด์•ผ ํ•˜๋Š” ๋Œ€์ƒ์ด ๋งŽ์•„์งˆ์ˆ˜๋ก ์ƒ์„ฑ์ž์˜ ์ธ์ž๊ฐ€ ๋Š˜์–ด๋‚œ๋‹ค. ์ด๋Š” ์˜์กด๊ด€๊ณ„์˜ ๋ณต์žก์„ฑ์„ ์‰ฝ๊ฒŒ ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๋ฏ€๋กœ ๋ฆฌํŒฉํ† ๋ง์˜ ์‹ค๋งˆ๋ฆฌ๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

2. DI ์ปจํ…Œ์ด๋„ˆ์™€์˜ ๋‚ฎ์€ ๊ฒฐํ•ฉ๋„

ํ•„๋“œ ์ฃผ์ž…์„ ์‚ฌ์šฉํ•˜๋ฉด ์˜์กด ํด๋ž˜์Šค๋ฅผ ๊ณง๋ฐ”๋กœ ์ธ์Šคํ„ด์Šคํ™” ์‹œํ‚ฌ ์ˆ˜ ์—†๋‹ค. ๋งŒ์•ฝ IoC ์ปจํ…Œ์ด๋„ˆ ๋ฐ–์˜ ํ™˜๊ฒฝ์—์„œ ์˜์กด์„ฑ์„ ์ฃผ์ž…๋ฐ›๋Š” ํด๋ž˜์Šค์˜ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•  ๋•Œ, Reflection์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ• ์™ธ์—๋Š” ์ฐธ์กฐํ•  ๋ฐฉ๋ฒ•์ด ์—†๋‹ค. ์ƒ์„ฑ์ž ๋˜๋Š” ์„ธํ„ฐ๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ์˜์กด ๊ฐ์ฒด ํ•„๋“œ๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์—†๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

์ƒ์„ฑ์€ ์ƒ์„ฑ์ž๋กœ ์˜์กด์„ฑ์„ ์ฃผ์ž…๋ฐ›๊ธฐ ๋•Œ๋ฌธ์— IoC ์ปจํ…Œ์ด๋„ˆ์— ์˜์กดํ•˜์ง€ ์•Š๊ณ  ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ณ , ๊ทธ ๋•๋ถ„์— ํ…Œ์ŠคํŠธ์—์„œ๋„ ๋” ์šฉ์ดํ•จ์„ ๋ณด์ธ๋‹ค.

3. ํ•„๋“œ์˜ ๋ถˆ๋ณ€์„ฑ ๋ณด์žฅ

ํ•„๋“œ ์ฃผ์ž…์€ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์˜์กด์„ฑ์„ Reflection์œผ๋กœ ์ฃผ์ž…๋ฐ›๊ธฐ ๋•Œ๋ฌธ์— ํ•„๋“œ ๋ณ€์ˆ˜๋ฅผ ๋ถˆ๋ณ€์œผ๋กœ ์„ ์–ธํ•  ์ˆ˜ ์—†๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์ƒ์„ฑ์ž ์ฃผ์ž…์€ ํ•„๋“œ๋ฅผ final๋กœ ์„ ์–ธํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ฐ์ฒด์˜ ๋ณ€๊ฒฝ์— ๋”ฐ๋ฅธ ๋น„์šฉ์„ ์ ˆ์•ฝํ•  ์ˆ˜ ์žˆ๋‹ค.

4. ์ˆœํ™˜ ์˜์กด ๋ฐฉ์ง€

์ƒ์„ฑ์ž ์ฃผ์ž…์—์„œ๋Š” ์ˆœํ™˜ ์˜์กด์„ฑ์„ ๊ฐ€์งˆ ๊ฒฝ์šฐ BeanCurrentlyInCreationException์ด ๋ฐœ์ƒํ•ด์„œ ๋ฌธ์ œ ์ƒํ™ฉ์„ ์•Œ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค.

โœจย Spring DL(Dependency Lookup) : ์˜์กด๊ด€๊ณ„ ๊ฒ€์ƒ‰

public Store() {
	AnnotationConfigApplicationContext context =
 		new AnnotationConfigApplicationContext(ItemFactory.class);

	this.connectionMaker = context.getBean("item", Item.class);
}

์˜์กด๊ด€๊ณ„๋ฅผ ๋งบ๋Š” ๋ฐฉ๋ฒ•์ด ์™ธ๋ถ€๋กœ๋ถ€ํ„ฐ์˜ ์ฃผ์ž…์ด ์•„๋‹ˆ๋ผ ์Šค์Šค๋กœ ๊ฒ€์ƒ‰์„ ์ด์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์˜์กด๊ด€๊ณ„ ๊ฒ€์ƒ‰(dependency lookup)์ด๋ผ๊ณ  ๋ถˆ๋ฆฐ๋‹ค.

์˜์กด๊ด€๊ณ„ ๊ฒ€์ƒ‰์€ ์ž์‹ ์ด ํ•„์š”๋กœ ํ•˜๋Š” ์˜์กด ์˜ค๋ธŒ์ ํŠธ๋ฅผ ๋Šฅ๋™์ ์œผ๋กœ ์ฐพ๋Š”๋‹ค.

์˜์กด๊ด€๊ณ„ ๊ฒ€์ƒ‰์€ ๋Ÿฐํƒ€์ž„ ์‹œ ์˜์กด๊ด€๊ณ„๋ฅผ ๋งบ์„ ์˜ค๋ธŒ์ ํŠธ๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ๊ฒƒ๊ณผ ์˜ค๋ธŒ์ ํŠธ์˜ ์ƒ์„ฑ ์ž‘์—…์€ ์™ธ๋ถ€ ์ปจํ…Œ์ด๋„ˆ์—๊ฒŒ IoC๋กœ ๋งก๊ธฐ์ง€๋งŒ, ์ด๋ฅผ ๊ฐ€์ ธ์˜ฌ ๋•Œ๋Š” ๋ฉ”์†Œ๋“œ๋‚˜ ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•œ ์ฃผ์ž… ๋Œ€์‹  ์Šค์Šค๋กœ ์ปจํ…Œ์ด๋„ˆ์—๊ฒŒ ์š”์ฒญํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•œ๋‹ค.

โœจDI vs DL

์˜์กด๊ด€๊ณ„ ์ฃผ์ž… ์ชฝ์ด ํ›จ์”ฌ ๋‹จ์ˆœํ•˜๊ณ  ๊น”๋”ํ•˜๋‹ค.

์‚ฌ์šฉ์ž์— ๋Œ€ํ•œ DB ์ •๋ณด๋ฅผ ์–ด๋–ป๊ฒŒ ๊ฐ€์ ธ์˜ฌ ๊ฒƒ์ธ๊ฐ€์— ์ง‘์ค‘ํ•ด์•ผ ํ•˜๋Š” UserDao์—์„œ ์Šคํ”„๋ง์ด๋‚˜ ์˜ค๋ธŒ์ ํŠธ ํŒฉํ† ๋ฆฌ๋ฅผ ๋งŒ๋“ค๊ณ  API๋ฅผ ์ด์šฉํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ ์„ž์—ฌ ์žˆ๋Š” ๊ฒƒ์€ ์–ด์ƒ‰ํ•˜๋‹ค. ๋Œ€๊ฐœ๋Š” ์˜์กด๊ด€๊ณ„ ์ฃผ์ž… ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๋Š” ํŽธ์ด ๋‚ซ๋‹ค.

์˜์กด๊ด€๊ณ„ ๊ฒ€์ƒ‰ ๋ฐฉ์‹์—์„œ๋Š” ๊ฒ€์ƒ‰ํ•˜๋Š” ์˜ค๋ธŒ์ ํŠธ๋Š” ์ž์‹ ์ด ์Šคํ”„๋ง์˜ ๋นˆ์ผ ํ•„์š”๊ฐ€ ์—†์œผ๋ฏ€๋กœ, ๋นˆ์ด ์•„๋‹Œ ๊ฐ์ฒด์˜ ๊ฒฝ์šฐ ์˜์กด๊ด€๊ณ„ ๊ฒ€์ƒ‰์„ ์‚ฌ์šฉํ•œ๋‹ค.

  • ํ† ๋น„์˜ ์Šคํ”„๋ง 1์žฅ

๐Ÿš€ย ์š”์•ฝ

IoC : ์ œ์–ด์˜ ์—ญ์ „, ์ƒ์œ„ ๋ชจ๋“ˆ์ด ํ•˜์œ„ ๋ชจ๋“ˆ ํ๋ฆ„์„ ์ œ์–ดํ•˜๋Š” GoF์— ๋“ฑ์žฅํ•˜๋Š” ๋””์ž์ธ ์›์น™(ํ• ๋ฆฌ์šฐ๋“œ ์›์น™)

DIP : ์˜์กด์„ฑ ์—ญ์ „ ์›์น™, ์ƒ์œ„ ๋ชจ๋“ˆ์ด ํ•˜์œ„ ๋ชจ๋“ˆ์˜ ๊ตฌ์ฒด ํด๋ž˜์Šค๊ฐ€ ์•„๋‹Œ ์ถ”์ƒํ™”์— ์˜์กดํ•˜๋Š” SOLID ๋””์ž์ธ ์›์น™

DI : ์˜์กด์„ฑ ์ฃผ์ž…, ๋ชจ๋“ˆ(๊ฐ์ฒด) ๊ฐ„ ์˜์กด์„ฑ์„ new๋กœ ์ง์ ‘ ์ •์˜ํ•˜์ง€ ์•Š๊ณ  ์™ธ๋ถ€์—์„œ ์ฃผ์ž…ํ•˜๋Š” ๋””์ž์ธ ํŒจํ„ด. (๊ผญ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•œ ์ฃผ์ž…์ผ ํ•„์š”๋Š” ์—†๋‹ค.)

Spring DI/IoC : ์Šคํ”„๋ง์—์„œ๋Š” ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ปจํ…์ŠคํŠธ๋ผ๋Š” IoC/DI ์ปจํ…Œ์ด๋„ˆ๋ฅผ ํ†ตํ•ด bean์œผ๋กœ ๋“ฑ๋ก๋œ ๊ฐ์ฒด์˜ ์˜์กด๊ด€๊ณ„๋ฅผ ์ž๋™์œผ๋กœ ์ฃผ์ž…ํ•ด์ค€๋‹ค.

์ด๋•Œ DI ๋ฐฉ์‹์—๋Š” ์ด 3๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค. ๊ทธ์ค‘ ์ƒ์„ฑ์ž ์ฃผ์ž… ๋ฐฉ์‹์ด ์ œ์ผ ๊ถŒ์žฅ๋œ๋‹ค. ์˜์กด๊ด€๊ณ„ ํŒŒ์•…์ด ์‰ฌ์›Œ ๋‹จ์ผ์ฑ…์ž„์›์น™์„ ์ง€ํ‚ค๋„๋ก ๋•๊ณ , DI ์ปจํ…Œ์ด๋„ˆ ๋ฐ–์—์„œ๋„ ๊ฐ์ฒด ์ฃผ์ž…์ด ๊ฐ€๋Šฅํ•˜๊ณ , ํ•„๋“œ ๋ถˆ๋ณ€์„ฑ์ด ๋ณด์žฅ๋˜๋ฉฐ, ์ˆœํ™˜ ์˜์กด์ด ๋ฐฉ์ง€๋œ๋‹ค.

์Šคํ”„๋ง์—์„  DI ๋Œ€์‹  DL์„ ํ†ตํ•ด์„œ๋„ IoC๋ฅผ ์ง€ํ‚ฌ ์ˆ˜ ์žˆ๋„๋ก ์ง€์›ํ•œ๋‹ค. DL์€ ๊ฐ์ฒด ์ƒ๋ช…์ฃผ๊ธฐ ๊ด€๋ฆฌ๋ฅผ IoC ์ปจํ…Œ์ด๋„ˆ์—์„œ ํ•˜๋˜, ์˜์กด์„ฑ์„ ์ฃผ์ž…๋ฐ›๋Š” ๋Œ€์‹  ์ง์ ‘ ์ปจํ…Œ์ด๋„ˆ์—์„œ ๊ฒ€์ƒ‰ํ•ด ๊ฐ€์ ธ์˜ค๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค. ๋นˆ ๋ฐ”๊นฅ์—์„œ ๋นˆ ๊ฐ์ฒด์— ์ ‘๊ทผํ•˜๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

์ฐธ๊ณ ์ž๋ฃŒ

Dependency Injection, IoC, DIP, IoC container์ •๋ฆฌ

https://johngrib.github.io/wiki/hollywood-principle/#:~:text=๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋ ˆ์ž„์›Œํฌ์™€,๋•Œ๋•Œ๋กœ ํ—๋ฆฌ์šฐ๋“œ ์›์น™์ด๋ผ๊ณ ๋„ ํ•ฉ๋‹ˆ๋‹ค.

Core Technologies

https://black-jin0427.tistory.com/194

Dependency Injection, IoC, DIP, IoC container์ •๋ฆฌ

ํ† ๋น„์˜ ์Šคํ”„๋ง 1์žฅ

์™œ Constructor Injection์„ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š”๊ฐ€?

profile
๐ŸŒฑ ํ•จ๊ป˜ ์ž๋ผ๋Š” ์ค‘์ž…๋‹ˆ๋‹ค ๐Ÿš€ rerub0831@gmail.com

0๊ฐœ์˜ ๋Œ“๊ธ€