IoC (Inversion of Controll)

πŸ” κ°œμš”

  • IoCλŠ” 객체 생성/μ΄ˆκΈ°ν™”/μ˜μ‘΄μ„± μ—°κ²°μ˜ μ œμ–΄κΆŒμ„ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œ μ»¨ν…Œμ΄λ„ˆλ‘œ λ’€μ§‘λŠ” 원칙이닀. (예: ν”„λ ˆμž„μ›Œν¬)
  • Spring에선 IoC μ»¨ν…Œμ΄λ„ˆ(BeanFactory/ApplicationContext) κ°€ μ–΄λ…Έν…Œμ΄μ…˜μ„ 읽어 Bean을 μƒμ„±Β·μ£Όμž…Β·κ΄€λ¦¬ ν•œλ‹€.
  • DI(μ˜μ‘΄μ„± μ£Όμž…) λŠ” IoCλ₯Ό κ΅¬ν˜„ν•˜λŠ” 핡심 λ©”μ»€λ‹ˆμ¦˜μ΄λ‹€.

☝🏻 ν•œμ€„ μš”μ•½

IoC λŠ” 객체의 μƒμ„±Β·μˆ˜λͺ…Β·μ˜μ‘΄μ„± 관리λ₯Ό κ°œλ°œμžκ°€ μ•„λ‹Œ ν”„λ ˆμž„μ›Œν¬κ°€ λ‹΄λ‹Ήν•˜λ„λ‘ μ„€κ³„ν•˜λŠ” 원칙이닀.


πŸ€” μ™œ ν•„μš”ν•œκ°€?

  • new ν‚€μ›Œλ“œλ‘œ 직접 μƒμ„±ν•˜λ©΄ κ΅¬ν˜„ ν›„ ꡐ체가 μ–΄λ €μ›Œ 결합도↑ (ν…ŒμŠ€νŠΈ/ν™•μž₯/ν™˜κ²½ μ „ν™˜μ΄ νž˜λ“¦)
  • 객체 생λͺ…μ£ΌκΈ° 관리(μ΄ˆκΈ°ν™”, 정리)와 aop μ μš©μ— ν•œκ³„

Spring IoCΒ :Β Spring Container & Bean

κ·Έλ ‡λ‹€λ©΄ μŠ€ν”„λ§μ€ μ–΄λ–»κ²Œ 객체λ₯Ό μƒμ„±ν•˜κ³  μ£Όμž…ν•  수 있게 ν•΄μ£ΌλŠ” 것인가?

κ²°λ‘ λΆ€ν„° λ§ν•˜μžλ©΄,Β Spring Container λΌλŠ” 녀석이 β€˜κ°μ²΄ μ •μ˜β€™λ₯Ό 미리 읽고, κ·Έ μ •μ˜λ₯Ό 기반으둜 객체λ₯Ό μƒμ„±ν•˜κ³ , μ˜μ‘΄μ„±μ„ μ£Όμž…ν•˜λ©°, 생성주기λ₯Ό κ΄€λ¦¬ν•œλ‹€.

  • ApplicationContext : BeanFactory의 ν™•μž₯. λ©”μ‹œμ§€μ†ŒμŠ€, 이벀트, ν™˜κ²½, AOP λ“± 인프라λ₯Ό ν¬ν•¨ν•œλ‹€.

Spring Boot의 μžλ™κ΅¬μ„± 은 쑰건(@Conditional)에 따라 κΈ°λ³Έ λΉˆμ„ μ œκ³΅ν•˜λŠ” λ ˆμ΄μ–΄λ‘œ, IoC μ»¨ν…Œμ΄λ„ˆ μœ„μ—μ„œ λ™μž‘ν•œλ‹€.


πŸ”§ μ˜ˆμ‹œ

(A) 직접 생성 - 결합도 λ†’μŒ

public class Communication implements Steps {
	private final Greeting greeting;
	private final Farewell farewell;
	private final Sender sender;
 
	public Communication() {
		this.greeting = new EnglishGreeting();
		this.farewell = new EnglishFarewell();
		this.sender = new ConsoleSender();
	}
 
	// ...
	
}

μœ„ μ½”λ“œμ—μ„œ 각 κ΅¬ν˜„μ²΄ ν΄λž˜μŠ€λ“€μ„ λ‹€λ₯Έ 클래슀둜 μˆ˜μ •ν•˜κ³  μ‹ΆμœΌλ©΄ μ–΄λ–»κ²Œ ν•΄μ•Όν• κΉŒ?

public Communication() { 
	this.greeting = new KoreanGreeting(); 
	this.farewell = new EnglishFarewell(); 
	this.sender = new ConsoleSender(); 
}

λ¬Όλ‘  μœ„μ²˜λŸΌ μ‰½κ²Œ μˆ˜μ •ν•  수 μžˆλ‹€.

κ·ΈλŸ¬λ‚˜, 이 communication() κ³Ό 같은 ν΄λž˜μŠ€κ°€ λ§Žμ•„μ§„λ‹€λ©΄, 일일이 λ‹€ ν•˜λ‚˜μ”© μˆ˜μ •ν•΄μ€˜μ•Ό ν•œλ‹€λŠ” λΆˆνŽΈν•¨μ΄ 생긴닀.

이 과정을 κ°œλ°œμžκ°€ ν•˜μ§€μ•Šκ²Œ ν”„λ ˆμž„μ›Œν¬κ°€ λŒ€μ‹  ν•˜λŠ” 것을 IoC 라 ν•˜κ³ , μŠ€ν”„λ§μ—μ„œλŠ” 이λ₯ΌΒ @AutowiredΒ λ‚˜Β @ComponentΒ κ°™μ€Β μ˜μ‘΄μ„±μ£Όμž…(DI) 으둜 ν•΄κ²°ν•œλ‹€.

(B) IoC/DI 적용 - μƒμ„±μž μ£Όμž…

@Component
public class Communication {
  private final Greeting greeting;
  private final Farewell farewell;
  private final Sender sender;
 
  public Communication(Greeting greeting, Farewell farewell, Sender sender) {
    this.greeting = greeting;
    this.farewell = farewell;
    this.sender = sender;
  }
}
 
@Configuration
@ComponentScan  // Greeting/Farewell/Sender κ΅¬ν˜„μ²΄μ— @Component
public class AppConfig { }

⚠️ μ£Όμ˜ν•  점

  • IoC β‰  DI β‰  AOP: DIλŠ” IoC의 κ΅¬ν˜„μ΄κ³ , AOPλŠ” νš‘λ‹¨ 관심사 뢄리 기법 쀑 ν•˜λ‚˜μΌ 뿐이닀!
  • @Autowired ν•„λ“œ μ£Όμž…λ³΄λ‹€ μƒμ„±μž μ£Όμž… ꢌμž₯ (λΆˆλ³€μ„±/ν…ŒμŠ€νŠΈ 용이)
  • β€œμ»¨ν…Œμ΄λ„ˆκ°€ β€˜κ°μ²΄ μ •μ˜β€™λ₯Ό 미리 μ½λŠ”λ‹€β€ β†’ μ •ν™•νžˆλŠ” ꡬ성 메타데이터λ₯Ό μŠ€μΊ”/νŒŒμ‹±ν•΄ 빈 μ •μ˜λ₯Ό λ§Œλ“€κ³  κ΄€λ¦¬ν•œλ‹€.

πŸ”— κ΄€λ ¨

  • DI - IoCλ₯Ό κ΅¬ν˜„ν•˜λŠ” νŒ¨ν„΄
  • auto-configuration - 쑰건에 λ”°λ₯Έ Bean μžλ™ 등둝
  • external-configuration - ν™˜κ²½/ν”„λ‘œν•„ 기반 μ„€μ • 뢄리