๐Ÿ“Œ SpringBoot Auto Configuration


ํ…Œ์ฝ”ํ†ก์„ ๋ณด๊ณ  ์ถ”๊ฐ€๋กœ ํ•™์Šตํ•œ ๋‚ด์šฉ๋“ค

์Šคํ”„๋ง ๋ถ€ํŠธ๋Š” component-scan์„ ํ†ตํ•ด component๋ฅผ ์ฐพ๊ณ  bean์„ ์ƒ์„ฑํ•œ๋‹ค.
์ด ๊ณผ์ •์—์„œ ์šฐ๋ฆฌ๊ฐ€ ์„ค์ •ํ•œ bean๋“ค์ด ์ƒ์„ฑ๋œ๋‹ค.
๊ทธ๋ฆฌ๊ณ  ์ด ๊ณผ์ •์—์„œ spring boot์˜ auto configuration์— ์˜ํ•ด ์ถ”๊ฐ€์ ์ธ bean๋“ค๋„ ํ•จ๊ป˜ ์ƒ์„ฑ๋œ๋‹ค.

Spring Boot AutoConfiguration์ด๋ž€?

  • ํด๋ž˜์Šค ํŒจ์Šค์— ์กด์žฌํ•˜๋Š” dependecy๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ spring ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ž๋™์œผ๋กœ ๊ตฌ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•
  • ์Šคํ”„๋ง ๋ถ€ํŠธ๋Š” web, h2, jdbc๋“ฑ ์—ฌ๋Ÿฌ ์ž๋™ ์„ค์ •์„ ์ œ๊ณต (starter)
  • ํŠน์ • Bean์„ ์ •์˜ํ•  ํ•„์š” ์—†๊ธฐ ๋•Œ๋ฌธ์— ๊ฐœ๋ฐœ์ด ๋” ๋น ๋ฅด๊ณ  ์‰ฌ์›Œ์ง
  • ์Šคํ”„๋ง๋ถ€ํŠธ์—์„  @SpringBootApplication์— ์žˆ๋Š” EnableAutoConfiguration ๋กœ ๊ฐ€๋Šฅ

@SpringBootAutoConfiguration

  • @SpringBootConfiguration : ์Šคํ”„๋ง์˜ @Configuration์„ ๋Œ€์ฒดํ•˜๋Š” ์Šคํ”„๋ง ๋ถ€ํŠธ ์ „์šฉ ์„ค์ • ์–ด๋…ธํ…Œ์ด์…˜
  • @EnableAutoConfiguration : auto configuration ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๊ฒ ๋‹ค๋Š” ์„ค์ •. ํด๋ž˜์Šค ํŒจ์Šค์— ์ง€์ •๋œ ๋‚ด์šฉ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์„ค์ •์„ ์ž๋™ํ™”. ์ผ๋ฐ˜์ ์œผ๋กœ @ComponentScan ์™€ ํ•จ๊ป˜ ์“ฐ์ž„

๊ทธ๋Ÿฐ๋ฐ ์šฐ๋ฆฌ๊ฐ€ ์ •์˜ํ•œ Bean๊ณผ Spring Boot๊ฐ€ ์ •์˜ํ•œ Bean์ด ์ถฉ๋Œํ•˜๋ฉด? ๋˜ํ•œ ๋ถˆํ•„์š”ํ•œ Bean๋“ค๋„ ๊ฐ™์ด ์ƒ์„ฑ๋œ๋‹ค๋ฉด?

@Condition๊ณผ @ConditionalOnXxx์„ ์ด์šฉํ•ด์„œ ์ด์™€ ๊ฐ™์€ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•œ๋‹ค.

spring.factories

์œ„์˜ ๋‘ ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ดํŽด๋ณด๊ธฐ ์ „์— auto configuration์— ํ•„์š”ํ•œ ํŒŒ์ผ๋“ค์„ ์‚ดํŽด๋ณด์ž.

Auto Configure

spring-boot-autoconfigure/META-INF/spring.factories ์—๋Š” ์Šคํ”„๋ง ๋ถ€ํŠธ๊ฐ€ ๋ฏธ๋ฆฌ ์ •์˜ํ•ด๋‘” auto configuration ์ •๋ณด๊ฐ€ ๋“ค์–ด์žˆ๋‹ค.
์—ฌ๊ธฐ์—๋Š” ์ž๋™ ์„ค์ •์˜ target ํด๋ž˜์Šค ๋ชฉ๋ก๋“ค์ด ๋‚˜์—ด๋˜์–ด ์žˆ๊ณ , ์—ฌ๊ธฐ์— ์„ ์–ธ๋œ ํด๋ž˜์Šค๋“ค์ด @EnableConfiguration ์‚ฌ์šฉ ์‹œ target์ด ๋œ๋‹ค.

@Conditional? @ConditionalOnXxx?

  • Sprig 4.0๋ถ€ํ„ฐ ์ถ”๊ฐ€๋œ ์–ด๋…ธํ…Œ์ด์…˜

spring.factories ์— ์žˆ๋Š” ํด๋ž˜์Šค๋“ค ์ค‘ ์ต์ˆ™ํ•œ org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\ ๋ฅผ ์˜ˆ์‹œ๋กœ ๋ณด์ž.

  • @ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class }) ์„ค์ •์„ ํ†ตํ•ด ํ•ด๋‹น ํด๋ž˜์Šค ํŒŒ์ผ์ด ์กด์žฌํ•ด์•ผ ์„ค์ •์„ ํ™œ์„ฑํ™” ํ•จ์„ ๋ช…์‹œ
  • @ConditionalOnMissingBean(type = "io.r2dbc.spi.ConnectionFactory") ์„ค์ •์„ ํ†ตํ•ด ํ•ด๋‹น Bean์ด ์กด์žฌํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ ์„ค์ •์„ ํ™œ์„ฑํ™” ํ•จ์„ ๋ช…์‹œ

์ด๋Ÿฌํ•œ ์„ค์ •๋“ค ๋•๋ถ„์— ์šฐ๋ฆฌ๊ฐ€ ์ •์˜ํ•œ Bean๊ณผ Spring Boot๊ฐ€ ์ •์˜ํ•œ Bean์ด ์ถฉ๋Œํ•˜๋Š” ๋ฌธ์ œ, ๋ถˆํ•„์š”ํ•œ Bean๋“ค์ด ์ƒ์„ฑ๋˜๋Š” ๋ฌธ์ œ ๋“ฑ์„ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

AutoConfigurationImportFilter

๊ทธ๋Ÿฐ๋ฐ ์‚ฌ์‹ค auto configuration์—์„œ ์ด @Condition ์„ ๋ฌด์กฐ๊ฑด ํƒ€๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋‹ค.
spring.factories ์—๋Š” AutoConfigurationImportFilter ์„ค์ •์ด ์กด์žฌํ•œ๋‹ค.
์•„๋ž˜์™€ ๊ฐ™์€ ํ•„ํ„ฐ๋“ค์€ ๊ฐ AutoConfiguration์ด ๊ฐ€์ง„ @Conditional ์„ ๊ฐ€์ง€๊ณ  ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š”์ง€ ํ•„ํ„ฐ๋ง์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.
์กฐ๊ฑด์ด ๋งž์ง€ ์•Š์„ ๊ฒฝ์šฐ, AutoConfiguration์ด ๋™์ž‘ํ•˜์ง€ ์•Š๋„๋ก ์ œ์™ธ์‹œํ‚ค๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.

  • OnBeanCondition : ํŠน์ • bean๋“ค์˜ ์กด์žฌ์œ ๋ฌด์— ๋Œ€ํ•ด์„œ ๋‹ค๋ฃจ๋Š” ํ•„ํ„ฐ
    • @ConditionalOnBean, @ConditionalOnMissingBean, @ConditionalOnSingleCandidate
  • OnClassCondition : ํŠน์ • class๋“ค์˜ ์กด์žฌ์œ ๋ฌด์— ๋Œ€ํ•ด์„œ ๋‹ค๋ฃจ๋Š” ํ•„ํ„ฐ
    • @ConditionalOnClass, @ConditionalOnMissingClass
  • OnWebApplicationCondition : WebApplicationContext์˜ ์กด์žฌ์œ ๋ฌด์— ๋Œ€ํ•ด์„œ ๋‹ค๋ฃจ๋Š” ํ•„ํ„ฐ
    • @ConditionalOnWebApplication, @ConditionalOnNotWebApplication

๊ทธ๋ ‡๋‹ค๋ฉด ์ด ์ž๋™ ์„ค์ •๋“ค์€ ์–ด๋–ป๊ฒŒ ๋ถˆ๋Ÿฌ์™€์งˆ๊นŒ?

@Import(AutoConfigurationImportSelector.class)

@SpringbootApplication ์–ด๋…ธํ…Œ์ด์…˜ ๋‚ด๋ถ€์— ์žˆ๋˜ @Import(AutoConfigurationImportSelector.class) ๋Š” ์ž๋™ ์„ค์ •์„ ์ง€์›ํ•ด์ฃผ๋ฉฐ, importํ•˜๊ณ  ์žˆ๋Š” AutoConfigurationImportSelector.class๊ฐ€ META-INF/spring.factories ์— ์ •์˜๋œ ์ž๋™ ์„ค์ •ํ•  ํด๋ž˜์Šค๋“ค์„ ๋ถˆ๋Ÿฌ์˜จ๋‹ค.