Spring 은 @Component λ“±κ³Ό 같은 νŠΉλ³„ν•œ annotation 듀에 λŒ€ν•˜μ—¬ scan 을 μˆ˜ν–‰ν•œλ‹€. 이후 μžλ™μœΌλ‘œ Spring Container 에 이듀을 Bean 으둜 λ“±λ‘λœλ‹€.

더 λ‚΄λΆ€μ μœΌλ‘œ λ“€μ–΄κ°€λ³΄μž. Spring Framework 의 λˆ„κ°€ scan 을 μˆ˜ν–‰ν•˜λŠ” 것인가? 그리고 λˆ„κ°€ Bean 으둜 λ“±λ‘ν•˜λŠ” 것인가?

SpringBootApplication

Spring Initializr κ°€ μžλ™μœΌλ‘œ 생성해쀀 Spring project 의 Main Spring Boot Application class μ½”λ“œλ₯Ό μ‚΄νŽ΄λ³΄λ©΄ μœ„μͺ½μ— @SpringBootApplication annotation 을 μ‚¬μš©ν•˜μ˜€κ³ , 이λ₯Ό μ‚¬μš©ν•˜κΈ° μœ„ν•˜μ—¬ ν•΄λ‹Ή package κ°€ import 된 것을 μ•Œ 수 μžˆλ‹€.

λ‚΄λΆ€ κ΅¬ν˜„μœΌλ‘œ 듀어가보면, @SpringBootApplication annotation 은 μœ„μ™€ 같이 @EnableAutoConfiguration, @ComponentScan, @Configuration 이 ν¬ν•¨λ˜μ–΄ μžˆλŠ” 것을 λ³Ό 수 μžˆλ‹€. 각각의 κΈ°λŠ₯은 λ‹€μŒκ³Ό κ°™λ‹€.

  • @EnableAutoConfiguration : Spring Bootμ—μ„œ classpath 에 μžˆλŠ” 라이브러리λ₯Ό 기반으둜 ν•„μš”ν•œ 섀정을 μžλ™μœΌλ‘œ ꡬ성
  • @ComponentScan : μ§€μ •λœ package 와 ν•˜μœ„ package λ₯Ό μŠ€μΊ”ν•˜μ—¬Β @Component,Β @Service,Β @Controller,Β @RepositoryΒ λ“±κ³Ό 같은 annotation 이 뢙은 class λ₯Ό μžλ™μœΌλ‘œ Bean Definition 에 등둝
  • @Configuration : @Bean annotation 을 ν†΅ν•˜μ—¬ extra Beans λ₯Ό λ“±λ‘ν•˜λŠ” Bean μ •μ˜ class μž„μ„ λ‚˜νƒ€λƒ„
SpringApplication

μ΄λ²ˆμ—λŠ” SpringBootApplication μœ„μ— import 된 SpringApplication 이닀.

SpringApplication 의 SpringApplication.run() 은 Spring Boot Application 의 Bootstrap 을 μˆ˜ν–‰ν•œλ‹€. μ—¬κΈ°μ„œΒ Bootstrap 은 application 을 μ‹€ν–‰ κ°€λŠ₯ν•œ μƒνƒœλ‘œ λ§Œλ“œλŠ”Β μ΄ˆκΈ°ν™” 및 μ€€λΉ„ 과정을 μ˜λ―Έν•œλ‹€.

그럼 Bootstrap 과정을 μˆœμ„œλŒ€λ‘œ μ‚΄νŽ΄λ³΄μž.

  1. SpringApplication.run() μ‹€ν–‰
  2. SpringApplication 객체 생성
    • SpringApplication 객체λ₯Ό μ΄ˆκΈ°ν™”ν•˜κ³  classpath μ—μ„œ servlet κ΄€λ ¨ library λ₯Ό 확인, servlet libraryt κ°€ μ‘΄μž¬ν•˜λ©΄ μ›Ή app, μ—†μœΌλ©΄ λΉ„μ›Ή app 인지λ₯Ό 감지
  3. ν™˜κ²½ μ„€μ • 및 ν”„λ‘œνŒŒμΌ 적용
    • application.propertiesΒ νŒŒμΌμ„ 읽어 ν™˜κ²½ λ³€μˆ˜μ™€ ν”„λ‘œνŒŒμΌμ„ μ„€μ •
    • ApplicationEnvironmentPreparedEventλ₯Ό λ°œμƒμ‹œμΌœ ν™˜κ²½μ΄ μ€€λΉ„λ˜μ—ˆμŒμ„ μ•Œλ¦Ό
  4. λ°°λ„ˆ 좜λ ₯
    • Spring Boot λ°°λ„ˆ(κΈ°λ³Έ ASCII μ•„νŠΈ)λ₯Ό μ½˜μ†”μ— 좜λ ₯ν•˜μ—¬ application μ‹œμž‘μ„ μ•Œλ¦Ό
  5. ApplicationContext 생성 및 μ΄ˆκΈ°ν™”
    • ApplicationContext 생성
      • μ›Ή/λΉ„μ›Ή app 인지에 λ”°λΌμ„œ Spring IoC Container 인 AnnotationConfigApplicationContextΒ λ˜λŠ”Β AnnotationConfigServletWebServerApplicationContext λ₯Ό 생성
    • Bean definition 등둝 (Component Scan)
      • @ComponentScan에 μ˜ν•΄ classpath μ—μ„œ μŠ€μΊ”λœ 클래슀(@Component,Β @Service,Β @Controller,Β @Repository) λ₯Ό Bean definition 으둜 등둝
      • μ‹€μ œ μŠ€μΊ” μž‘μ—…μ€Β ClassPathBeanDefinitionScannerκ°€ μˆ˜ν–‰ν•˜λ©°, Bean definition 은 context λ‚΄λΆ€μ˜ Bean Factory 에 μ €μž₯
      • default λ‘œλŠ” Main Spring Boot application 이 μ‘΄μž¬ν•˜λŠ” package μ—λ§Œ scan λ²”μœ„κ°€ κ΅­ν•œλ˜μ§€λ§Œ, @SpringBootApplication( scanBasePackages={ ... } ) λ₯Ό ν†΅ν•˜μ—¬ μΆ”κ°€ κ°€λŠ₯
  6. Auto-Configuration
    • @SpringBootApplication 의 @EnableAutoConfiguration 에 μ˜ν•΄ classpath 의 library λ₯Ό κ°μ§€ν•˜κ³ , ν•„μš”ν•œ Bean κ³Ό 섀정을 μžλ™μœΌλ‘œ μΆ”κ°€ (λ°μ΄ν„°λ² μ΄μŠ€ μ„€μ •, μ›Ή μ„œλ²„ μ„€μ • λ“±)
  7. 빈 μΈμŠ€ν„΄μŠ€ν™” 및 μ˜μ‘΄μ„± μ£Όμž…:
    • ApplicationContextλŠ” λ“±λ‘λœ Bean definition 을 기반으둜 μ‹€μ œ Bean object λ₯Ό 생성
    • DI λ₯Ό 톡해 Bean κ°„μ˜ 관계λ₯Ό μ„€μ •
  8. λ‚΄μž₯ μ›Ή μ„œλ²„ μ‹œμž‘ (μ›Ή μ• ν”Œλ¦¬μΌ€μ΄μ…˜)
    • classpath 에 μ›Ή κ΄€λ ¨ library κ°€ 있으면 λ‚΄μž₯ Tomcat λ“±μ˜ μ›Ήμ„œλ²„λ₯Ό μ‹œμž‘
    • HTTP μš”μ²­μ„ μ²˜λ¦¬ν•  μ€€λΉ„λ₯Ό μ™„λ£Œ
  9. μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ‹€ν–‰ μ€€λΉ„ μ™„λ£Œ

μ§€κΈˆκΉŒμ§€ λ‚˜μ˜¨ λ‚΄μš©μ„ μ€‘μ‹¬μœΌλ‘œ μš”μ•½ν•˜λ©΄ λ‹€μŒκ³Ό 같은 μˆœμ„œλ‘œ μ§„ν–‰λœλ‹€.

SpringApplication 생성 > ApplicationContext 생성 > Component Scan > Bean Definition 등둝 > Bean 생성

Component Scanning Test

μœ„μ—μ„œ @ComponentScan 을 ν†΅ν•œ Component Scanning 은 기본적으둜 Main Spring Boot Application 이 μ‘΄μž¬ν•˜λŠ” package μ—λ§Œ κ΅­ν•œλœλ‹€κ³  λ§ν–ˆλ‹€. κ·ΈλŸ¬λ‚˜ ν˜„μž¬ μœ„μ˜ μƒν™©μ—μ„œλŠ”, com.lucvs.util μ΄λΌλŠ” λ‹€λ₯Έ package μ—λ§Œ @Component annotation 이 μ‚¬μš©λœ class 듀이 μ‘΄μž¬ν•˜κ³  μžˆλ‹€.

μ΄λ‘ μ μœΌλ‘œλŠ” μ•ˆ λœλ‹€λŠ” 것을 μ•Œμ§€λ§Œ, ν•œλ²ˆ Application 을 싀행해보면 μ–΄λ–»κ²Œ 될까?

보톡 error λŠ” 기뢄이 μ’‹μ§€ μ•Šμ§€λ§Œ, μ˜λ„λœ error λ₯Ό λ°œμƒμ‹œν‚¬ λ•Œμ—λŠ” μ•½κ°„μ˜ 쾌감이 μ‘΄μž¬ν•œλ‹€. μ—­μ‹œλ‚˜ error κ°€ λ°œμƒν•œ 것을 λ³Ό 수 μžˆλ‹€. error message λ₯Ό 보면 com.lucvs.util.Coach μ΄λΌλŠ” type 의 Bean 을 찾을 수 μ—†λ‹€κ³  ν•œλ‹€.

λ”°λΌμ„œ, @SpringBootApplication annotation 에 explicit ν•˜κ²Œ base package 듀을 listing ν•΄μ£Όμ–΄μ•Ό ν•œλ‹€.