Spring Application 이 μ‹œμž‘λ˜κ³  λ‚œ 뒀에 Spring 은, 더 μ •ν™•ν•˜κ²Œ λ§ν•˜λ©΄ ApplicationContext κ°€ λͺ¨λ“  Bean 에 λŒ€ν•œ instance λ₯Ό μƒμ„±ν•˜κ³ , initialize ν•œλ‹€.

Lazy Initialization 은 λͺ¨λ“  Bean 을 μ‹€ν–‰ μ΄ˆκΈ°μ— initialize ν•˜λŠ” 것이 μ•„λ‹ˆλΌ, DI λ“±κ³Ό 같은 explicit ν•œ request κ°€ μžˆμ„ λ•Œ ApplicationContext κ°€ Bean 을 μƒμ„±ν•˜κ³  initialize ν•˜λŠ” 것이닀. Application 의 startup μ‹œκ°„μ„ λΉ λ₯΄κ²Œ ν•  수 μžˆλŠ” μž₯점이 μ‘΄μž¬ν•œλ‹€. λ™μž‘ μˆœμ„œλŠ” λ‹€μŒκ³Ό κ°™λ‹€.

  1. /dailywork endpoint 에 μ ‘κ·Ό
  2. FootballCoach 에 λŒ€ν•œ instance λ₯Ό 이 λ•Œ 생성
  3. 이후 DemoController 에 λŒ€ν•œ instance λ₯Ό μƒμ„±ν•˜κ³  FootballCoach λ₯Ό inject

μ‚¬μš© 방법은 λ‹¨μˆœνžˆ Lazy Initialization 을 μ‹œν‚€κ³  싢은 Bean 의 class 에 @Lazy annotation 을 μΆ”κ°€ν•˜λ©΄ λœλ‹€. λͺ¨λ“  Bean 듀에 λŒ€ν•˜μ—¬ Lazy λ₯Ό μ„€μ •ν•˜κ³  싢을 λ•ŒλŠ” μ–΄λ–»κ²Œ ν• κΉŒ?

λ¬Όλ‘  Bean 이 적으면 λͺ¨λ“  class 에 λŒ€ν•˜μ—¬ @Lazy annotation 을 μ„€μ •ν•΄μ£Όλ©΄ λ˜μ§€λ§Œ, μ•„λ‹ˆλΌλ©΄ μ•½κ°„μ˜ λ¬΄μ‹ν•œ 노동이 ν•„μš”ν•  것이닀. 이에 Spring 은 global configuration ν•˜λŠ” 방법을 μ œκ³΅ν•˜λŠ”λ°, application.properties νŒŒμΌμ— spring.main.lazy-initialization=true codeline 을 μΆ”κ°€ν•΄μ£Όλ©΄ λœλ‹€.

Disadvatages

Lazy Initialization 은 Appilication 의 μ‹œμž‘ μ‹œκ°„μ„ λ‹¨μΆ•ν•˜κ³ , μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” Bean 은 μƒμ„±ν•˜μ§€ μ•ŠμŒμœΌλ‘œ λ©”λͺ¨λ¦¬ μ†ŒλΉ„λ₯Ό 쀄일 수 μžˆλŠ” λ“±μ˜ μž₯점이 μ‘΄μž¬ν•œλ‹€.

ν•˜μ§€λ§Œ λ‹€μŒμ˜ 단점이 μ‘΄μž¬ν•œλ‹€.

    1. 문제 발견 μ§€μ—°
    • Bean이 μš”μ²­λ  λ•ŒκΉŒμ§€ μ΄ˆκΈ°ν™”λ˜μ§€ μ•ŠμœΌλ―€λ‘œ, 잘λͺ»λœ μ„€μ •μ΄λ‚˜ μ˜μ‘΄μ„± λ¬Έμ œλŠ” μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ‹€ν–‰ 쀑에야 발견될 수 있음
  1. 첫 μš”μ²­ μ‹œ μ§€μ—°
    • Bean이 처음 μ‚¬μš©λ  λ•Œ μ΄ˆκΈ°ν™”κ°€ μ΄λ£¨μ–΄μ§€λ―€λ‘œ, 첫 번째 μš”μ²­ μ‹œ μ„±λŠ₯ μ €ν•˜κ°€ λ°œμƒν•  수 있음
  2. λ³΅μž‘ν•œ μ˜μ‘΄μ„± 관리
    • μ—¬λŸ¬ Lazy Bean이 μ„œλ‘œ μ˜μ‘΄ν•˜λŠ” 경우, μ˜μ‘΄μ„± κ·Έλž˜ν”„κ°€ λ³΅μž‘ν•΄μ§€κ³  μˆœν™˜ μ˜μ‘΄μ„± λ¬Έμ œκ°€ λ°œμƒν•  수 있음
  3. κ³ λΆ€ν•˜ μƒν™©μ—μ„œ μ„±λŠ₯ μ €ν•˜
    • μ΄ˆκΈ°ν™”κ°€ ν•„μš”ν•œ Bean이 λ§Žμ€ 경우, λ™μ‹œμ— μ—¬λŸ¬ μš”μ²­μ΄ λ“€μ–΄μ˜€λ©΄ μ΄ˆκΈ°ν™” μž‘μ—…μ΄ λͺ°λ € μ„±λŠ₯ 병λͺ© ν˜„μƒ λ°œμƒ κ°€λŠ₯

λ”°λΌμ„œ premature optimization 의 함정에 λΉ μ§€λ©΄ μ•ˆ λœλ‹€. 이에 κ°œλ°œμžλŠ” Application 의 ꡬ쑰와 μš”κ΅¬μ‚¬ν•­μ„ 잘 νŒŒμ•…ν•˜μ—¬ 적절히 ν™œμš©ν•΄μ•Ό ν•œλ‹€.

β€œPremature optimization is the root of all evil”

Donald Knuth

Lazy Initialization - Test

μš°μ„  λ‹€μ‹œ @Qualifier λ₯Ό μ‚¬μš©ν•˜λŠ” λ°©μ‹μœΌλ‘œ λ°”κΎΈκ³ , 각 Bean λ“€μ˜ constructor 에 Bean 의 이름을 좜λ ₯ν•˜λ„λ‘ λ§Œλ“€μ—ˆλ‹€. Application 을 μ‹€ν–‰ν•΄λ³΄μž.

보면 ApplicationContext κ°€ Bean 듀을 μƒμ„±ν•˜κ³  initialize ν•˜μ—¬ 각 Bean 에 ν•΄λ‹Ήν•˜λŠ” 좜λ ₯을 λ³Ό 수 μžˆλ‹€.

이제 BasketballCoach 만 Lazy Bean 으둜 μ§€μ •ν•˜μž.

@Component  
@Lazy  
public class BasketballCoach implements Coach { ... }

Application 을 싀행해보면,

μœ„μ™€ 같이 BaseballCoach Bean 만 μ œμ™Έν•˜κ³  initialized 된 것을 λ³Ό 수 μžˆλ‹€.

global ν•˜κ²Œ Lazy Initialization 을 μ μš©ν•˜λ©΄ console μ—μ„œλŠ” μ–΄λ–»κ²Œ 좜λ ₯이 λ°œμƒν• κΉŒ? application.properties λ₯Ό ν†΅ν•˜μ—¬ global Lazy Initialization 을 μ„€μ •ν•˜κ³  console 을 μ‚΄νŽ΄λ³΄λ©΄ λ‹€μŒκ³Ό κ°™λ‹€.

ApplicationContext κ°€ intialized 된 이후에 ApplicationContext λ₯Ό ν†΅ν•΄μ„œ λ°”λ‘œ Bean 을 μƒμ„±ν•˜κ³  initialize ν•˜λŠ” 것이 μ•„λ‹ˆλΌ, Application 이 μ‹€ν–‰λœ 이후에 /workout endpoint 에 μ ‘κ·Όν•  λ•Œ Bean 이 μƒμ„±λ˜κ³  initialized 된 것을 μ•Œ 수 μžˆλ‹€.