๐Ÿš€ Spring Boot ์ž๋™ ์„ค์ •(Auto-configuration) ์›๋ฆฌ ์ดํ•ดํ•˜๊ธฐ ๐Ÿง 

์ฝ˜ํ…์ธ  ๋Œ€ํ‘œ ์ด๋ฏธ์ง€ - ๐Ÿš€ Spring Boot ์ž๋™ ์„ค์ •(Auto-configuration) ์›๋ฆฌ ์ดํ•ดํ•˜๊ธฐ ๐Ÿง 

 

 

์•ˆ๋…•ํ•˜์„ธ์š”, ์—ฌ๋Ÿฌ๋ถ„! ์˜ค๋Š˜์€ Spring Boot์˜ ํ•ต์‹ฌ ๊ธฐ๋Šฅ ์ค‘ ํ•˜๋‚˜์ธ ์ž๋™ ์„ค์ •(Auto-configuration)์— ๋Œ€ํ•ด ๊นŠ์ด ํŒŒํ—ค์ณ๋ณผ ๊ฑฐ์˜ˆ์š”. ์ด ๊ธ€์„ ์ฝ๊ณ  ๋‚˜๋ฉด ์—ฌ๋Ÿฌ๋ถ„๋„ Spring Boot ๋งˆ์Šคํ„ฐ๊ฐ€ ๋  ์ˆ˜ ์žˆ์„ ๊ฑฐ์˜ˆ์š”! ใ…‹ใ…‹ใ…‹ ์ž, ๊ทธ๋Ÿผ ์‹œ์ž‘ํ•ด๋ณผ๊นŒ์š”? ๐ŸŽ‰

์ฐธ๊ณ : ์ด ๊ธ€์€ '์žฌ๋Šฅ๋„ท'์˜ '์ง€์‹์ธ์˜ ์ˆฒ' ๋ฉ”๋‰ด์— ๋“ฑ๋ก๋  ์˜ˆ์ •์ด์—์š”. ์žฌ๋Šฅ๋„ท์€ ๋‹ค์–‘ํ•œ ์žฌ๋Šฅ์„ ๊ฑฐ๋ž˜ํ•˜๋Š” ํ”Œ๋žซํผ์ธ๋ฐ, ์—ฌ๋Ÿฌ๋ถ„์˜ Spring Boot ์‹ค๋ ฅ๋„ ์ถฉ๋ถ„ํžˆ ์žฌ๋Šฅ์ด ๋  ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค! ๐Ÿ˜‰

๐Ÿค” Spring Boot ์ž๋™ ์„ค์ •์ด ๋ญ๊ธธ๋ž˜?

Spring Boot์˜ ์ž๋™ ์„ค์ •... ๋ญ”๊ฐ€ ์žˆ์–ด ๋ณด์ด๋Š” ์ด๋ฆ„์ด์ฃ ? ใ…‹ใ…‹ใ…‹ ์‚ฌ์‹ค ์ด ๊ธฐ๋Šฅ์€ Spring Boot์˜ ํ•ต์‹ฌ ์ค‘์˜ ํ•ต์‹ฌ์ด์—์š”! ์ž๋™ ์„ค์ • ๋•๋ถ„์— ์šฐ๋ฆฌ๋Š” ๋ณต์žกํ•œ ์„ค์ • ์—†์ด๋„ Spring ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‰ฝ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค. ๐Ÿ‘

์ž๋™ ์„ค์ •์ด ์—†๋˜ ์‹œ์ ˆ์„ ์ƒ์ƒํ•ด๋ณผ๊นŒ์š”? XML ํŒŒ์ผ์— ๋นˆ์„ ์ผ์ผ์ด ๋“ฑ๋กํ•˜๊ณ , ํ”„๋กœํผํ‹ฐ ํŒŒ์ผ์„ ๋งŒ๋“ค์–ด ์„ค์ •ํ•˜๊ณ ... ์•„, ์ƒ๊ฐ๋งŒ ํ•ด๋„ ๋จธ๋ฆฌ๊ฐ€ ์•„ํŒŒ์š”! ๐Ÿ˜ฑ ํ•˜์ง€๋งŒ Spring Boot๋Š” ์ด๋Ÿฐ ๊ณ ํ†ต์—์„œ ์šฐ๋ฆฌ๋ฅผ ํ•ด๋ฐฉ์‹œ์ผœ์คฌ์–ด์š”.

TMI: Spring Boot๊ฐ€ ์—†๋˜ ์‹œ์ ˆ, ๊ฐœ๋ฐœ์ž๋“ค์€ ์„ค์ • ํŒŒ์ผ ๋•Œ๋ฌธ์— ๋จธ๋ฆฌ๊ฐ€ ๋น ์งˆ ์ง€๊ฒฝ์ด์—ˆ๋‹ค๊ณ  ํ•ด์š”. ์ง€๊ธˆ ์ƒ๊ฐํ•˜๋ฉด ์›ƒ์Œ๋งŒ ๋‚˜์˜ค๋„ค์š”. ใ…‹ใ…‹ใ…‹

๐ŸŽญ ์ž๋™ ์„ค์ •์˜ ๋งˆ๋ฒ•, ์–ด๋–ป๊ฒŒ ์ด๋ค„์ง€๋Š” ๊ฑธ๊นŒ?

์ž๋™ ์„ค์ •์˜ ์›๋ฆฌ๋ฅผ ์ดํ•ดํ•˜๋ ค๋ฉด, ๋จผ์ € Spring Boot์˜ ์ฒ ํ•™์„ ์•Œ์•„์•ผ ํ•ด์š”. Spring Boot๋Š” "๊ด€๋ก€์  ์„ค์ •(Convention over Configuration)"์ด๋ผ๋Š” ๊ฐœ๋…์„ ๋”ฐ๋ฅด๊ณ  ์žˆ์–ด์š”. ์‰ฝ๊ฒŒ ๋งํ•ด, "๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ์— ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ผ!"๋ผ๊ณ  ๋ฏธ๋ฆฌ ์ •ํ•ด๋†“์€ ๊ฑฐ์ฃ .

์˜ˆ๋ฅผ ๋“ค์–ด, ์—ฌ๋Ÿฌ๋ถ„์ด ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋งŒ๋“ ๋‹ค๊ณ  ํ•ด๋ณผ๊นŒ์š”? Spring Boot๋Š” ์ž๋™์œผ๋กœ Tomcat ์„œ๋ฒ„๋ฅผ ์„ค์ •ํ•ด์ค˜์š”. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๊ณ ์š”? JPA์™€ Hibernate๋„ ์•Œ์•„์„œ ์„ค์ •ํ•ด์ค๋‹ˆ๋‹ค. ์™„์ „ ๊ฐœ์ด๋“ ์•„๋‹ˆ์—์š”? ๐Ÿ˜Ž

Spring Boot ์ž๋™ ์„ค์ •์˜ ๋งˆ๋ฒ• Spring Boot ์ž๋™ ์„ค์ •์˜ ๋งˆ๋ฒ• Web Database Security Logging

์ด ๊ทธ๋ฆผ์„ ๋ณด๋ฉด Spring Boot๊ฐ€ ์–ผ๋งˆ๋‚˜ ๋งŽ์€ ๊ฒƒ์„ ์ž๋™์œผ๋กœ ์„ค์ •ํ•ด์ฃผ๋Š”์ง€ ํ•œ๋ˆˆ์— ์•Œ ์ˆ˜ ์žˆ์ฃ ? ์›น, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค, ๋ณด์•ˆ, ๋กœ๊น… ๋“ฑ ๋‹ค์–‘ํ•œ ์˜์—ญ์„ Spring Boot๊ฐ€ ์•Œ์•„์„œ ์ฑ™๊ฒจ์ค๋‹ˆ๋‹ค. ์™„์ „ ๋งŒ๋Šฅ ํ•ด๊ฒฐ์‚ฌ ์•„๋‹ˆ์—์š”? ใ…‹ใ…‹ใ…‹

๐Ÿ•ต๏ธโ€โ™‚๏ธ ์ž๋™ ์„ค์ •์˜ ๋น„๋ฐ€์„ ํŒŒํ—ค์ณ๋ณด์ž!

์ž, ์ด์ œ ์ž๋™ ์„ค์ •์˜ ๋น„๋ฐ€์„ ํŒŒํ—ค์ณ๋ณผ ์‹œ๊ฐ„์ด์—์š”! Spring Boot์˜ ์ž๋™ ์„ค์ •์€ ํฌ๊ฒŒ ์„ธ ๊ฐ€์ง€ ์š”์†Œ๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ์–ด์š”.

  • @EnableAutoConfiguration: ์ž๋™ ์„ค์ •์˜ ์‹œ์ž‘์ 
  • @Conditional: ์กฐ๊ฑด๋ถ€ ์„ค์ •์˜ ๋งˆ๋ฒ•์‚ฌ
  • spring.factories: ์ž๋™ ์„ค์ •์˜ ๋ชฉ๋ก์„ ๊ด€๋ฆฌํ•˜๋Š” ํŒŒ์ผ

์ด ์„ธ ๊ฐ€์ง€๋งŒ ์ œ๋Œ€๋กœ ์ดํ•ดํ•˜๋ฉด, ์—ฌ๋Ÿฌ๋ถ„๋„ Spring Boot ์ž๋™ ์„ค์ •์˜ ๋‹ฌ์ธ์ด ๋  ์ˆ˜ ์žˆ์–ด์š”! ๐Ÿ˜Ž

1. @EnableAutoConfiguration: ์ž๋™ ์„ค์ •์˜ ์‹œ์ž‘์  ๐Ÿšฆ

@EnableAutoConfiguration์€ Spring Boot ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์‹œ์ž‘์ ์ด์—์š”. ์ด ์–ด๋…ธํ…Œ์ด์…˜์€ @SpringBootApplication ์•ˆ์— ํฌํ•จ๋˜์–ด ์žˆ์ฃ . ์—ฌ๋Ÿฌ๋ถ„์ด main ๋ฉ”์„œ๋“œ์— @SpringBootApplication์„ ๋ถ™์ผ ๋•Œ๋งˆ๋‹ค, ์ž๋™์œผ๋กœ @EnableAutoConfiguration๋„ ํ•จ๊ป˜ ์ ์šฉ๋˜๋Š” ๊ฑฐ์˜ˆ์š”.

@SpringBootApplication
public class MyAwesomeApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyAwesomeApplication.class, args);
    }
}

์ด ์ฝ”๋“œ๋งŒ ๋ด๋„ Spring Boot๊ฐ€ ์–ผ๋งˆ๋‚˜ ๊ฐ„๋‹จํ•œ์ง€ ์•Œ ์ˆ˜ ์žˆ์ฃ ? ใ…‹ใ…‹ใ…‹ ์ด๊ฒŒ ๋ฐ”๋กœ Spring Boot์˜ ๋งค๋ ฅ์ด์—์š”! ๐Ÿ˜

2. @Conditional: ์กฐ๊ฑด๋ถ€ ์„ค์ •์˜ ๋งˆ๋ฒ•์‚ฌ ๐Ÿง™โ€โ™‚๏ธ

@Conditional์€ Spring Boot์˜ ์ž๋™ ์„ค์ •์—์„œ ์ •๋ง ์ค‘์š”ํ•œ ์—ญํ• ์„ ํ•ด์š”. ์ด ์–ด๋…ธํ…Œ์ด์…˜์€ "์ด๋Ÿฐ ์กฐ๊ฑด์ผ ๋•Œ๋งŒ ์ด ์„ค์ •์„ ์ ์šฉํ•ด!"๋ผ๊ณ  ๋งํ•ด์ฃผ๋Š” ๊ฑฐ์ฃ . ์™„์ „ ๋˜‘๋˜‘ํ•˜์ง€ ์•Š๋‚˜์š”?

์˜ˆ๋ฅผ ๋“ค์–ด, @ConditionalOnClass๋ผ๋Š” ์–ด๋…ธํ…Œ์ด์…˜์ด ์žˆ์–ด์š”. ์ด ์–ด๋…ธํ…Œ์ด์…˜์€ "ํŠน์ • ํด๋ž˜์Šค๊ฐ€ ํด๋ž˜์ŠคํŒจ์Šค์— ์žˆ์„ ๋•Œ๋งŒ ์ด ์„ค์ •์„ ์ ์šฉํ•ด!"๋ผ๊ณ  ๋งํ•ด์ฃผ๋Š” ๊ฑฐ์˜ˆ์š”.

@Configuration
@ConditionalOnClass(DataSource.class)
public class DataSourceAutoConfiguration {
    // ๋ฐ์ดํ„ฐ์†Œ์Šค ๊ด€๋ จ ์„ค์ •
}

์ด ์ฝ”๋“œ๋Š” DataSource ํด๋ž˜์Šค๊ฐ€ ํด๋ž˜์ŠคํŒจ์Šค์— ์žˆ์„ ๋•Œ๋งŒ ๋ฐ์ดํ„ฐ์†Œ์Šค ๊ด€๋ จ ์„ค์ •์„ ์ ์šฉํ•œ๋‹ค๋Š” ๋œป์ด์—์š”. ์™„์ „ ์Šค๋งˆํŠธํ•˜์ฃ ? ๐Ÿ‘Œ

3. spring.factories: ์ž๋™ ์„ค์ •์˜ ๋ชฉ๋ก์„ ๊ด€๋ฆฌํ•˜๋Š” ํŒŒ์ผ ๐Ÿ“œ

spring.factories ํŒŒ์ผ์€ ์ž๋™ ์„ค์ •์˜ ๋ชฉ๋ก์„ ๊ด€๋ฆฌํ•˜๋Š” ์•„์ฃผ ์ค‘์š”ํ•œ ํŒŒ์ผ์ด์—์š”. ์ด ํŒŒ์ผ์€ META-INF/spring.factories ๊ฒฝ๋กœ์— ์œ„์น˜ํ•ด ์žˆ์–ด์š”.

์ด ํŒŒ์ผ ์•ˆ์—๋Š” ์ž๋™ ์„ค์ • ํด๋ž˜์Šค๋“ค์˜ ๋ชฉ๋ก์ด ์žˆ์–ด์š”. Spring Boot๋Š” ์ด ํŒŒ์ผ์„ ์ฝ์–ด์„œ ์–ด๋–ค ์ž๋™ ์„ค์ •์„ ์ ์šฉํ• ์ง€ ๊ฒฐ์ •ํ•˜๋Š” ๊ฑฐ์ฃ .

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration

์ด๋Ÿฐ ์‹์œผ๋กœ ์ž๋™ ์„ค์ • ํด๋ž˜์Šค๋“ค์ด ๋‚˜์—ด๋˜์–ด ์žˆ์–ด์š”. ์™„์ „ ๋ฐฉ๋Œ€ํ•˜์ฃ ? ใ…‹ใ…‹ใ…‹

๐ŸŽญ ์ž๋™ ์„ค์ •์˜ ๋™์ž‘ ์›๋ฆฌ

์ž, ์ด์ œ ์ž๋™ ์„ค์ •์ด ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š”์ง€ ์ž์„ธํžˆ ์•Œ์•„๋ณผ๊นŒ์š”? ๋งˆ์น˜ ์—ฐ๊ทน์„ ๋ณด๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ์ƒ์ƒํ•ด๋ณด์„ธ์š”! ๐ŸŽญ

  1. 1๋ง‰: ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹œ์ž‘ ๐Ÿš€
    • Spring Boot ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค.
    • @SpringBootApplication ์–ด๋…ธํ…Œ์ด์…˜์ด ์ฒ˜๋ฆฌ๋˜๊ธฐ ์‹œ์ž‘ํ•ด์š”.
  2. 2๋ง‰: @EnableAutoConfiguration ๋“ฑ์žฅ ๐ŸŽญ
    • @EnableAutoConfiguration์ด ํ™œ์„ฑํ™”๋ฉ๋‹ˆ๋‹ค.
    • ์ด ์–ด๋…ธํ…Œ์ด์…˜์€ AutoConfigurationImportSelector๋ฅผ ๋ถˆ๋Ÿฌ์˜ต๋‹ˆ๋‹ค.
  3. 3๋ง‰: ์ž๋™ ์„ค์ • ํ›„๋ณด ํƒ์ƒ‰ ๐Ÿ•ต๏ธโ€โ™€๏ธ
    • AutoConfigurationImportSelector๊ฐ€ ํด๋ž˜์ŠคํŒจ์Šค์—์„œ META-INF/spring.factories ํŒŒ์ผ์„ ์ฐพ์Šต๋‹ˆ๋‹ค.
    • ์ด ํŒŒ์ผ์—์„œ EnableAutoConfiguration ํ‚ค์— ํ•ด๋‹นํ•˜๋Š” ์„ค์ • ํด๋ž˜์Šค๋“ค์„ ๋ชจ๋‘ ๋ถˆ๋Ÿฌ์˜ต๋‹ˆ๋‹ค.
  4. 4๋ง‰: ์กฐ๊ฑด ํ™•์ธ ๐Ÿง
    • ๊ฐ ์ž๋™ ์„ค์ • ํด๋ž˜์Šค์— ๋ถ™์€ @Conditional ์–ด๋…ธํ…Œ์ด์…˜์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
    • ์กฐ๊ฑด์ด ๋งž๋Š” ์„ค์ •๋งŒ ์ ์šฉํ•˜๊ณ , ๋งž์ง€ ์•Š๋Š” ์„ค์ •์€ ๋ฌด์‹œํ•ฉ๋‹ˆ๋‹ค.
  5. 5๋ง‰: ์ž๋™ ์„ค์ • ์ ์šฉ ๐ŸŽ‰
    • ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” ์„ค์ •๋“ค์ด Spring ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ปจํ…์ŠคํŠธ์— ๋“ฑ๋ก๋ฉ๋‹ˆ๋‹ค.
    • ์ด๋ ‡๊ฒŒ ๋“ฑ๋ก๋œ ์„ค์ •๋“ค์ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ ์šฉ๋˜๋Š” ๊ฑฐ์ฃ !

์™€~ ์ •๋ง ๋ณต์žกํ•ด ๋ณด์ด์ง€๋งŒ, Spring Boot๊ฐ€ ์ด ๋ชจ๋“  ๊ณผ์ •์„ ์ž๋™์œผ๋กœ ์ฒ˜๋ฆฌํ•ด์ฃผ๋‹ˆ๊นŒ ์šฐ๋ฆฌ๋Š” ํŽธํ•˜๊ฒŒ ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ๋Š” ๊ฑฐ์˜ˆ์š”! ๐Ÿ‘

Spring Boot ์ž๋™ ์„ค์ • ๋™์ž‘ ์›๋ฆฌ ์‹œ์ž‘ @Enable ํƒ์ƒ‰ ์กฐ๊ฑด ์ ์šฉ Spring Boot ์ž๋™ ์„ค์ • ํ”„๋กœ์„ธ์Šค

์ด ๊ทธ๋ฆผ์„ ๋ณด๋ฉด Spring Boot์˜ ์ž๋™ ์„ค์ • ๊ณผ์ •์ด ํ•œ๋ˆˆ์— ๋“ค์–ด์˜ค์ฃ ? ์‹œ์ž‘๋ถ€ํ„ฐ ์ ์šฉ๊นŒ์ง€, ๋งˆ์น˜ assembly line์ฒ˜๋Ÿผ ์ˆœ์ฐจ์ ์œผ๋กœ ์ง„ํ–‰๋˜๋Š” ๋ชจ์Šต์ด ์ •๋ง ๋ฉ‹์žˆ์–ด์š”! ๐Ÿ˜

๐Ÿ” ์ž๋™ ์„ค์ • ์‚ดํŽด๋ณด๊ธฐ: ์‹ค์ œ ์˜ˆ์ œ๋กœ ์•Œ์•„๋ณด์ž!

์ž, ์ด์ œ ์‹ค์ œ ์˜ˆ์ œ๋ฅผ ํ†ตํ•ด ์ž๋™ ์„ค์ •์ด ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š”์ง€ ์ž์„ธํžˆ ์‚ดํŽด๋ณผ๊นŒ์š”? ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ์„ ์˜ˆ๋กœ ๋“ค์–ด๋ณผ๊ฒŒ์š”. ๐Ÿ—ƒ๏ธ

1. ์˜์กด์„ฑ ์ถ”๊ฐ€

๋จผ์ €, ํ”„๋กœ์ ํŠธ์˜ pom.xml ํŒŒ์ผ์— ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•ด์š”.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <scope>runtime</scope>
</dependency>

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด JPA์™€ H2 ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ด€๋ จ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ํ”„๋กœ์ ํŠธ์— ์ถ”๊ฐ€๋ผ์š”. Spring Boot๊ฐ€ ์ด๊ฑธ ๋ณด๊ณ  "์•„ํ•˜! ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„ค์ •์ด ํ•„์š”ํ•˜๊ตฌ๋‚˜!"๋ผ๊ณ  ์ƒ๊ฐํ•˜๋Š” ๊ฑฐ์ฃ . ใ…‹ใ…‹ใ…‹

2. ์ž๋™ ์„ค์ • ํด๋ž˜์Šค ์‚ดํŽด๋ณด๊ธฐ

Spring Boot๋Š” DataSourceAutoConfiguration ํด๋ž˜์Šค๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ์†Œ์Šค๋ฅผ ์ž๋™์œผ๋กœ ์„ค์ •ํ•ด์š”. ์ด ํด๋ž˜์Šค์˜ ์ผ๋ถ€๋ฅผ ์‚ดํŽด๋ณผ๊นŒ์š”?

@Configuration
@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
@EnableConfigurationProperties(DataSourceProperties.class)
@Import({ DataSourcePoolMetadataProvidersConfiguration.class,
    DataSourceInitializationConfiguration.class })
public class DataSourceAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public DataSourceInitializer dataSourceInitializer(DataSourceProperties properties,
            ApplicationContext applicationContext) {
        // ...
    }

    // ...
}

์šฐ์™€~ ๋ญ”๊ฐ€ ๋ณต์žกํ•ด ๋ณด์ด์ฃ ? ํ•˜์ง€๋งŒ ๊ฑฑ์ • ๋งˆ์„ธ์š”. ํ•˜๋‚˜์”ฉ ๋œฏ์–ด๋ณผ๊ฒŒ์š”! ๐Ÿ˜‰

  • @Configuration: ์ด ํด๋ž˜์Šค๊ฐ€ ์„ค์ • ํด๋ž˜์Šค๋ผ๋Š” ๊ฑธ ๋‚˜ํƒ€๋‚ด์š”.
  • @ConditionalOnClass: DataSource์™€ EmbeddedDatabaseType ํด๋ž˜์Šค๊ฐ€ ํด๋ž˜์ŠคํŒจ์Šค์— ์žˆ์„ ๋•Œ๋งŒ ์ด ์„ค์ •์„ ์ ์šฉํ•ด์š”.
  • @EnableConfigurationProperties: DataSourceProperties๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค˜์š”.
  • @Import: ๋‹ค๋ฅธ ์„ค์ • ํด๋ž˜์Šค๋“ค์„ ๊ฐ€์ ธ์™€์š”.
  • @Bean: ๋ฐ์ดํ„ฐ์†Œ์Šค ์ดˆ๊ธฐํ™”๋ฅผ ์œ„ํ•œ ๋นˆ์„ ์ƒ์„ฑํ•ด์š”.
  • @ConditionalOnMissingBean: ์ด๋ฏธ DataSourceInitializer ํƒ€์ž…์˜ ๋นˆ์ด ์—†์„ ๋•Œ๋งŒ ์ด ๋นˆ์„ ์ƒ์„ฑํ•ด์š”.

์ด๋ ‡๊ฒŒ Spring Boot๋Š” ์กฐ๊ฑด์„ ์ฒดํฌํ•˜๊ณ , ํ•„์š”ํ•œ ๋นˆ๋“ค์„ ์ƒ์„ฑํ•˜๋Š” ๊ฑฐ์˜ˆ์š”. ์™„์ „ ๋˜‘๋˜‘ํ•˜์ฃ ? ๐Ÿ‘จโ€๐Ÿ”ฌ

3. ํ”„๋กœํผํ‹ฐ ์„ค์ •

์ž๋™ ์„ค์ •์€ ๊ธฐ๋ณธ๊ฐ’์„ ์‚ฌ์šฉํ•˜์ง€๋งŒ, ์šฐ๋ฆฌ๊ฐ€ ์›ํ•˜๋Š” ๋Œ€๋กœ ์„ค์ •์„ ๋ณ€๊ฒฝํ•  ์ˆ˜๋„ ์žˆ์–ด์š”. application.properties ํŒŒ์ผ์— ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์„ค์ •์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์ฃ .

spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด Spring Boot๋Š” ์ด ์„ค์ •๊ฐ’์„ ์ฝ์–ด์„œ ๋ฐ์ดํ„ฐ์†Œ์Šค๋ฅผ ๊ตฌ์„ฑํ•ด์š”. ์šฐ๋ฆฌ๊ฐ€ ์ง์ ‘ ์„ค์ •ํ•˜์ง€ ์•Š์•„๋„ ๋˜๋‹ˆ๊นŒ ์ •๋ง ํŽธํ•˜์ฃ ? ๐Ÿ˜Ž

4. ์ž๋™ ์„ค์ • ๋™์ž‘ ํ™•์ธ

์ž, ์ด์ œ ์‹ค์ œ๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‹คํ–‰ํ•ด๋ณผ๊นŒ์š”? ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฐ„๋‹จํ•œ ์—”ํ‹ฐํ‹ฐ์™€ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋ฅผ ๋งŒ๋“ค์–ด๋ณผ๊ฒŒ์š”.

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String name;
    
    // getters and setters
}

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}

๊ทธ๋ฆฌ๊ณ  ๋ฉ”์ธ ํด๋ž˜์Šค์—์„œ ์ด๋ฅผ ์‚ฌ์šฉํ•ด๋ณผ๊ฒŒ์š”.

@SpringBootApplication
public class MyAwesomeApplication implements CommandLineRunner {

    @Autowired
    private UserRepository userRepository;

    public static void main(String[] args) {
        SpringApplication.run(MyAwesomeApplication.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        User user = new User();
        user.setName("Spring Boot Fan");
        userRepository.save(user);
        
        System.out.println("User saved: " + userRepository.findAll());
    }
}

์ด ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด, Spring Boot๊ฐ€ ์ž๋™์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์„ค์ •ํ•˜๊ณ , JPA๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๊ณ , ์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“  ์—”ํ‹ฐํ‹ฐ์™€ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค˜์š”. ์™„์ „ ์‹ ๊ธฐํ•˜์ง€ ์•Š๋‚˜์š”? ๐ŸŽ‰

๊ฟ€ํŒ: ์žฌ๋Šฅ๋„ท์—์„œ Spring Boot ๊ด€๋ จ ๊ฐ•์˜๋ฅผ ์ฐพ์•„๋ณด์„ธ์š”! ์‹ค์ œ ํ”„๋กœ์ ํŠธ ๊ฒฝํ—˜์ด ์žˆ๋Š” ์ „๋ฌธ๊ฐ€๋“ค์˜ ๊ฐ•์˜๋ฅผ ๋“ค์œผ๋ฉด ๋” ๋น ๋ฅด๊ฒŒ ์‹ค๋ ฅ์„ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์–ด์š”. ๐Ÿ˜‰

๐Ÿค” ์ž๋™ ์„ค์ •, ์ด๊ฒŒ ๋‹ค ์ข‹๊ธฐ๋งŒ ํ•œ ๊ฑธ๊นŒ?

์ž๋™ ์„ค์ •์ด ์ •๋ง ํŽธ๋ฆฌํ•˜๋‹ค๋Š” ๊ฑด ์•Œ๊ฒ ์–ด์š”. ํ•˜์ง€๋งŒ "์ด๊ฒŒ ๋‹ค ์ข‹๊ธฐ๋งŒ ํ•œ ๊ฑธ๊นŒ?" ํ•˜๋Š” ์˜๋ฌธ์ด ๋“ค ์ˆ˜ ์žˆ์ฃ . ์ž๋™ ์„ค์ •์˜ ์žฅ๋‹จ์ ์„ ํ•œ๋ฒˆ ์‚ดํŽด๋ณผ๊นŒ์š”?

์žฅ์  ๐Ÿ‘

  • ๋น ๋ฅธ ๊ฐœ๋ฐœ: ๋ณต์žกํ•œ ์„ค์ • ์—†์ด ๋ฐ”๋กœ ๊ฐœ๋ฐœ์„ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ์–ด์š”.
  • ํ‘œ์ค€ํ™”: ๋ชจ๋“  ํ”„๋กœ์ ํŠธ๊ฐ€ ๋น„์Šทํ•œ ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง€๊ฒŒ ๋˜์–ด ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์‰ฌ์›Œ์ ธ์š”.
  • ํŽธ๋ฆฌ์„ฑ: ๊ฐœ๋ฐœ์ž๊ฐ€ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์—๋งŒ ์ง‘์ค‘ํ•  ์ˆ˜ ์žˆ์–ด์š”.
  • ์œ ์—ฐ์„ฑ: ํ•„์š”ํ•˜๋‹ค๋ฉด ์–ธ์ œ๋“  ์„ค์ •์„ ์˜ค๋ฒ„๋ผ์ด๋“œํ•  ์ˆ˜ ์žˆ์–ด์š”.

๋‹จ์  ๐Ÿ‘Ž

  • ๋ธ”๋ž™๋ฐ•์Šค: ๋‚ด๋ถ€ ๋™์ž‘์„ ์ดํ•ดํ•˜๊ธฐ ์–ด๋ ค์šธ ์ˆ˜ ์žˆ์–ด์š”.
  • ์ œ์–ด๋ ฅ ์ƒ์‹ค: ๋•Œ๋กœ๋Š” ์›ํ•˜๋Š” ๋Œ€๋กœ ์ •ํ™•ํžˆ ์ œ์–ดํ•˜๊ธฐ ์–ด๋ ค์šธ ์ˆ˜ ์žˆ์–ด์š”.
  • ์„ฑ๋Šฅ: ๋ถˆํ•„์š”ํ•œ ์„ค์ •์ด ํฌํ•จ๋  ์ˆ˜ ์žˆ์–ด ์•ฝ๊ฐ„์˜ ์„ฑ๋Šฅ ์ €ํ•˜๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์–ด์š”.
  • ํ•™์Šต ๊ณก์„ : ์ž๋™ ์„ค์ •์„ ์™„์ „ํžˆ ์ดํ•ดํ•˜๊ณ  ํ™œ์šฉํ•˜๋Š” ๋ฐ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆด ์ˆ˜ ์žˆ์–ด์š”.

ํ•˜์ง€๋งŒ ์ด๋Ÿฐ ๋‹จ์ ๋“ค๋„ Spring Boot๋ฅผ ๊นŠ์ด ์ดํ•ดํ•˜๊ณ  ์ž˜ ํ™œ์šฉํ•˜๋ฉด ์ถฉ๋ถ„ํžˆ ๊ทน๋ณตํ•  ์ˆ˜ ์žˆ์–ด์š”. ๊ทธ๋Ÿฌ๋‹ˆ๊นŒ ๊ฑฑ์ • ๋งˆ์„ธ์š”! ๐Ÿ˜‰

๐Ÿ› ๏ธ ์ž๋™ ์„ค์ • ์ปค์Šคํ„ฐ๋งˆ์ด์ง•ํ•˜๊ธฐ

๋•Œ๋กœ๋Š” Spring Boot์˜ ์ž๋™ ์„ค์ •๋งŒ์œผ๋กœ๋Š” ๋ถ€์กฑํ•  ๋•Œ๊ฐ€ ์žˆ์–ด์š”. ๊ทธ๋Ÿด ๋•Œ๋Š” ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ• ๊นŒ์š”? ๊ฑฑ์ • ๋งˆ์„ธ์š”! Spring Boot๋Š” ์ž๋™ ์„ค์ •์„ ์ปค์Šคํ„ฐ๋งˆ์ด์ง•ํ•  ์ˆ˜ ์žˆ๋Š” ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•ด์š”. ๐Ÿ‘จโ€๐Ÿ”ง

1. ํ”„๋กœํผํ‹ฐ ํŒŒ์ผ ์‚ฌ์šฉํ•˜๊ธฐ

๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์€ application.properties ๋˜๋Š” application.yml ํŒŒ์ผ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฑฐ์˜ˆ์š”. ์˜ˆ๋ฅผ ๋“ค์–ด, ์„œ๋ฒ„ ํฌํŠธ๋ฅผ ๋ณ€๊ฒฝํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด:

server.port=8081

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์„œ๋ฒ„๊ฐ€ 8081 ํฌํŠธ์—์„œ ์‹คํ–‰๋ผ์š”. ์™„์ „ ์‰ฝ์ฃ ? ใ…‹ใ…‹ใ…‹

2. ํ”„๋กœํŒŒ์ผ ์‚ฌ์šฉํ•˜๊ธฐ

๋‹ค๋ฅธ ํ™˜๊ฒฝ(๊ฐœ๋ฐœ, ํ…Œ์ŠคํŠธ, ์šด์˜ ๋“ฑ)์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ์„ค์ •์„ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ํ”„๋กœํŒŒ์ผ์„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์–ด์š”.

spring.profiles.active=dev

---
spring.config.activate.on-profile=dev
server.port=8080

---
spring.config.activate.on-profile=prod
server.port=80

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์—์„œ๋Š” 8080 ํฌํŠธ๋ฅผ, ์šด์˜ ํ™˜๊ฒฝ์—์„œ๋Š” 80 ํฌํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋ผ์š”. ์™„์ „ ์Šค๋งˆํŠธํ•˜์ฃ ? ๐Ÿ˜Ž

3. ์ž๋ฐ” ์„ค์ • ํด๋ž˜์Šค ๋งŒ๋“ค๊ธฐ

์ข€ ๋” ๋ณต์žกํ•œ ์„ค์ •์ด ํ•„์š”ํ•˜๋‹ค๋ฉด ์ž๋ฐ” ์„ค์ • ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด์š”.

@Configuration
public class MyConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public MyCustomBean myCustomBean() {
        return new MyCustomBean();
    }
}

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด MyCustomBean์ด๋ผ๋Š” ๋นˆ์ด ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋ผ์š”. ๋ฌผ๋ก  ์ด๋ฏธ ์žˆ๋‹ค๋ฉด ์ƒ์„ฑ๋˜์ง€ ์•Š๊ฒ ์ฃ ? ๋˜‘๋˜‘ํ•ด! ๐Ÿ‘

4. ์ž๋™ ์„ค์ • ํด๋ž˜์Šค ๋งŒ๋“ค๊ธฐ

์ •๋ง ๋Œ€๋‹จํ•œ ๊ฑธ ๋งŒ๋“ค๊ณ  ์‹ถ๋‹ค๋ฉด, ์•„์˜ˆ ์ž๋™ ์„ค์ • ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ์–ด์š”.

@Configuration
@ConditionalOnClass(MyService.class)
@EnableConfigurationProperties(MyProperties.class)
public class MyAutoConfiguration {

    @Autowired
    private MyProperties properties;

    @Bean
    @ConditionalOnMissingBean
    public MyService myService() {
        return new MyServiceImpl(properties.getConfig());
    }
}

๊ทธ๋ฆฌ๊ณ  META-INF/spring.factories ํŒŒ์ผ์— ์ด ํด๋ž˜์Šค๋ฅผ ๋“ฑ๋กํ•˜๋ฉด ๋ผ์š”.

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.MyAutoConfiguration

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์—ฌ๋Ÿฌ๋ถ„๋งŒ์˜ ์ž๋™ ์„ค์ •์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด์š”. ์™„์ „ ํ”„๋กœ ๊ฐœ๋ฐœ์ž ๋Š๋‚Œ ๋‚˜์ง€ ์•Š๋‚˜์š”? ๐Ÿ˜Ž

๐Ÿงช ์ž๋™ ์„ค์ • ํ…Œ์ŠคํŠธํ•˜๊ธฐ

์ž๋™ ์„ค์ •์„ ๋งŒ๋“ค์—ˆ๋‹ค๋ฉด, ๋‹น์—ฐํžˆ ํ…Œ์ŠคํŠธ๋„ ํ•ด์•ผ๊ฒ ์ฃ ? Spring Boot๋Š” ์ž๋™ ์„ค์ •์„ ํ…Œ์ŠคํŠธํ•˜๊ธฐ ์œ„ํ•œ ๋‹ค์–‘ํ•œ ๋„๊ตฌ๋ฅผ ์ œ๊ณตํ•ด์š”. ํ•œ๋ฒˆ ์‚ดํŽด๋ณผ๊นŒ์š”? ๐Ÿ•ต๏ธโ€โ™‚๏ธ

1. @SpringBootTest ์‚ฌ์šฉํ•˜๊ธฐ

๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์€ @SpringBootTest ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฑฐ์˜ˆ์š”.

@SpringBootTest
class MyServiceTest {

    @Autowired
    private MyService myService;

    @Test
    void testMyService() {
        assertNotNull(myService);
        // ๋” ๋งŽ์€ ํ…Œ์ŠคํŠธ...
    }
}

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ „์ฒด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ปจํ…์ŠคํŠธ๋ฅผ ๋กœ๋“œํ•ด์„œ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ์–ด์š”. ์™„๋ฒฝํ•˜์ฃ ? ๐Ÿ‘Œ

2. @AutoConfigureMockMvc ์‚ฌ์šฉํ•˜๊ธฐ

์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ํ…Œ์ŠคํŠธํ•  ๋•Œ๋Š” @AutoConfigureMockMvc๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์š”.