[μ΄νŽ™ν‹°λΈŒ μžλ°”] Item05 μ™„λ²½κ³΅λž΅. μŠ€ν”„λ§ IOC

2023. 1. 16. 10:54ㆍJAVA/Effective JAVA

728x90

 

item05. μžμ›μ„ 직접 λͺ…μ‹œν•˜μ§€ 말고 μ˜μ‘΄κ°μ²΄μ£Όμž…μ„ μ‚¬μš©ν•˜λΌ. 

" p30. 의쑴 객체가 λ§Žμ€ κ²½μš°μ— Dagger, Guice, μŠ€ν”„λ§ 같은 의쑴 객체 μ£Όμž… ν”„λ ˆμž„μ›Œν¬ λ„μž…μ„ κ³ λ €ν•  수 μžˆλ‹€."

 

 

 

μŠ€ν”„λ§ IoC (Inversion Of Control) 

: BeanFactory, ApplicationContext

μ œμ–΄μ˜ μ—­μ „μ΄λž€ μš°μ„  자기 μ½”λ“œμ— λŒ€ν•œ μ œμ–΄κΆŒμ„ 자기 μžμ‹ μ΄ 가지고 μžˆμ§€ μ•Šκ³  μ™ΈλΆ€μ—μ„œ μ œμ–΄ν•˜λŠ” 경우λ₯Ό λ§ν•œλ‹€. 

 

λŒ€ν‘œμ μΈ 예둜 μŠ€ν”„λ§μ΄ μžˆλŠ”λ° μŠ€ν”„λ§ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œλŠ” 빈의 생성과 의쑴 관계 μ„€μ •, μ‚¬μš©, 제거 λ“±μ˜ μž‘μ—…μ„ μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ½”λ“œ λŒ€μ‹  μŠ€ν”„λ§ μ»¨ν…Œμ΄λ„ˆκ°€ λ‹΄λ‹Ήν•œλ‹€. 

-> 이λ₯Ό μŠ€ν”„λ§ μ»¨ν…Œμ΄λ„ˆκ°€ μ½”λ“œ λŒ€μ‹  μ˜€λΈŒμ νŠΈμ— λŒ€ν•œ μ œμ–΄κΆŒμ„ κ°–κ³  μžˆλ‹€κ³  ν•΄μ„œ IoC라고 ν•œλ‹€. 

 

 

SpellChecker

public class SpellChecker
{
   private Dictionary dictionary;
   
   public SpellChecker(Dictionary dictionary)
   {
      this.dictionary = dictionary;
   }
   
   public boolean isValid(String word)
   {
      return dictionary.contains(word);
   }
   
   public List<String> suggestions(String typo)
   {
      return dictionary.closeWordsTo(typo);
   }
}

 

SpringDictionary 

public class SpringDictionary implements Dictionary
{
   @Override
   public boolean contains(String word)
   {
      System.out.println("contains.word = " + word);
      return false;
   }
   
   @Override
   public List<String> closeWordsTo(String typo)
   {
      return null;
   }
}

-> SpellChecker와 SpringDictionaryλŠ” 보면 Spring IoCλ₯Ό μ‚¬μš©ν•œλ‹€κ³  ν•΄μ„œ μŠ€ν”„λ§ μ½”λ“œκ°€ μ‚¬μš©λ˜μ§€ μ•ŠλŠ” 것을 확인할 수 μžˆλ‹€. 

이건 μŠ€ν”„λ§μ˜ μ² ν•™? λ•Œλ¬ΈμΈλ° μŠ€ν”„λ§μ€ non-invasive라고 ν•΄μ„œ λΉ„μΉ¨νˆ¬μ μΈ μ½”λ“œλ₯Ό 지ν–₯ν•˜λŠ”λ° μ΄λŠ” μŠ€ν”„λ§μ˜ μ½”λ“œλ₯Ό λ…ΈμΆœν•˜μ§€ μ•ŠμœΌλ©΄μ„œλ„ μŠ€ν”„λ§μ΄ μ œκ³΅ν•˜λŠ” κΈ°λŠ₯을 μ‚¬μš©ν•  수 μžˆλ„λ‘ μ§€μ›ν•œλ‹€. 

 

 

AppConfig

@Configuration
public class AppConfig
{
   @Bean
   public SpellChecker spellChecker(Dictionary dictionary)
   {
      return new SpellChecker(dictionary);
   }
   
   @Bean
   public Dictionary dictionary()
   {
      return new SpringDictionary();
   }
   
}

그리고 @Configurationμ΄λΌλŠ” κ³³μ—μ„œ μ‚¬μš©ν•˜κ³ μž ν•˜λŠ” 객체λ₯Ό 빈(Bean: μŠ€ν”„λ§μ—μ„œ κ΄€λ¦¬ν•˜λŠ” 객체) 으둜 등둝해주고, μ˜μ‘΄κ΄€κ³„λ₯Ό μ„€μ •ν•΄μ£Όλ©΄ λœλ‹€. 

 

μ‚¬μš© μ½”λ“œ

public static void main(String[] args)
{
   ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
   SpellChecker spellChecker = applicationContext.getBean(SpellChecker.class); // 싱글톀
   spellChecker.isValid("test");
   
}

 

 

μŠ€ν”„λ§ IoC (Inversion Of Control) μ»¨ν…Œμ΄λ„ˆ μž₯점 

- μˆ˜λ§Žμ€ κ°œλ°œμžμ—κ²Œ κ²€μ¦λ˜μ—ˆμœΌλ©° μžλ°” ν‘œμ€€ 슀팩 (@Inject)도 μ§€μ›ν•œλ‹€. 

μŠ€ν”„λ§ IoC처럼 직접 μš°λ¦¬λ„ κ°œλ°œν•  수 μžˆμ§€λ§Œ μŠ€ν”„λ§ IoC μ»¨ν…Œμ΄λ„ˆλ₯Ό μ‚¬μš©ν•˜λ©΄ 쒋은 점은 μš°μ„  μ§€μ†μ μœΌλ‘œ 관리가 되고 있으며, κ°œμ„ λ˜κ³  있고, κΈ°λŠ₯이 점점 μΆ”κ°€λ˜κ³  μžˆλŠ” 이 μ˜€ν”ˆ μ†ŒμŠ€λ₯Ό μ‚¬μš©ν•˜λ©΄ μš°λ¦¬κ°€ ꡳ이 λ§Œλ“€ ν•„μš” 없이 μŠ€ν”„λ§μ„ μ‚¬μš©ν•˜λ©΄ λœλ‹€λŠ” νŽΈλ¦¬ν•¨μ΄ μžˆλ‹€. 

 

- μ†μ‰½κ²Œ 싱글톀 scopeλ₯Ό μ‚¬μš©ν•  수 μžˆλ‹€. 

싱글톀 scopeλ₯Ό λ§Œλ“€μ–΄μ„œ μ‚¬μš©ν•˜κΈ° νŽΈλ¦¬ν•˜λ‹€. (μŠ€ν”„λ§ μ»¨ν…Œμ΄λ„ˆ λ‚΄λΆ€μ—μ„œ 별닀λ₯Έ μž₯치 없이 싱글톀 κ°€λŠ₯) 

 

- 객체 생성(Bean) κ΄€λ ¨ 라이프사이클 μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ œκ³΅ν•œλ‹€.  

빈 생성 및 μ†Œλ©Έκ³Ό 같은 라이프사이클을 μŠ€ν”„λ§μ΄ 관리해쀀닀. (ex. μŠ€ν”„λ§ AOP: 라이프 사이클을 κ΄€λ¦¬ν•˜λ©΄μ„œ aop κΈ°λŠ₯을 μ œκ³΅ν•΄μ€Œ) 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

728x90