์ฝ˜ํ…์ธ  ๋Œ€ํ‘œ ์ด๋ฏธ์ง€ - ๐ŸŒฑ Spring Boot Externalized Configuration: ์™ธ๋ถ€ ์„ค์ • ๊ด€๋ฆฌ์˜ ์„ธ๊ณ„๋กœ ํ’๋ฉ! ๐ŸŠโ€โ™‚๏ธ

๐ŸŒฑ Spring Boot Externalized Configuration: ์™ธ๋ถ€ ์„ค์ • ๊ด€๋ฆฌ์˜ ์„ธ๊ณ„๋กœ ํ’๋ฉ! ๐ŸŠโ€โ™‚๏ธ

์•ˆ๋…•ํ•˜์„ธ์š”, ๊ฐœ๋ฐœ์ž ์—ฌ๋Ÿฌ๋ถ„! ์˜ค๋Š˜์€ Spring Boot์˜ ๊ฟ€ํŒ ์ค‘์—์„œ๋„ ๊ฟ€์ค‘์˜ ๊ฟ€์ธ Externalized Configuration์— ๋Œ€ํ•ด ๊นŠ์ด ํŒŒํ—ค์ณ๋ณผ ๊ฑฐ์˜ˆ์š”. ์ด๊ฑฐ ์•Œ๋ฉด ์—ฌ๋Ÿฌ๋ถ„์˜ ๊ฐœ๋ฐœ ์ธ์ƒ์ด 180๋„ ๋‹ฌ๋ผ์งˆ ๊ฑฐ์˜ˆ์š”, ์ง„์งœ๋ฃจ์š”! ใ…‹ใ…‹ใ…‹

์•„, ๊ทธ๋ฆฌ๊ณ  ์ž ๊น! ์—ฌ๋Ÿฌ๋ถ„, ํ˜น์‹œ ๋‹ค์–‘ํ•œ ์žฌ๋Šฅ์„ ๊ฑฐ๋ž˜ํ•  ์ˆ˜ ์žˆ๋Š” ํ”Œ๋žซํผ ์ฐพ๊ณ  ๊ณ„์…จ์–ด์š”? ๊ทธ๋ ‡๋‹ค๋ฉด ์žฌ๋Šฅ๋„ท์„ ํ•œ๋ฒˆ ์ฒดํฌํ•ด๋ณด์„ธ์š”! ๊ฐœ๋ฐœ ๊ด€๋ จ ์ง€์‹๋ถ€ํ„ฐ ๋‹ค์–‘ํ•œ ๋ถ„์•ผ์˜ ์žฌ๋Šฅ๊นŒ์ง€, ์—ฌ๋Ÿฌ๋ถ„์˜ ์‹ค๋ ฅ์„ ๋ฝ๋‚ด๊ณ  ์ƒˆ๋กœ์šด ๊ฒƒ์„ ๋ฐฐ์šธ ์ˆ˜ ์žˆ๋Š” ๊ณณ์ด์—์š”. ๐Ÿ‘จโ€๐Ÿซ๐Ÿ‘ฉโ€๐ŸŽจ

์ž, ์ด์ œ ๋ณธ๊ฒฉ์ ์œผ๋กœ Spring Boot์˜ ์™ธ๋ถ€ ์„ค์ • ๊ด€๋ฆฌ์— ๋Œ€ํ•ด ์•Œ์•„๋ณผ๊นŒ์š”? ์ค€๋น„๋˜์…จ๋‚˜์š”? 3, 2, 1... ๊ณ ๊ณ ์”ฝ! ๐Ÿš€

1. Externalized Configuration์ด ๋ญ๊ธธ๋ž˜? ๐Ÿค”

์—ฌ๋Ÿฌ๋ถ„, ํ˜น์‹œ ์ด๋Ÿฐ ๊ฒฝํ—˜ ์žˆ์œผ์„ธ์š”? ๊ฐœ๋ฐœํ•  ๋•Œ๋Š” ์ž˜ ๋Œ์•„๊ฐ€๋˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์‹ค์ œ ์„œ๋ฒ„์— ์˜ฌ๋ฆฌ๋ฉด ๊ฐ‘์ž๊ธฐ "์•—! ์ด๊ฒŒ ์™œ ์•ˆ ๋ผ?!" ํ•˜๋ฉด์„œ ๋ฉ˜๋ถ•์˜ค๋Š” ๊ทธ๋Ÿฐ ์ƒํ™ฉ... ๐Ÿ˜ฑ

๋ฐ”๋กœ ์ด๋Ÿฐ ์ƒํ™ฉ์„ ํ•ด๊ฒฐํ•ด์ฃผ๋Š” ๊ฒŒ Externalized Configuration์ด์—์š”! ์ด๊ฒŒ ๋ญ๋ƒ๊ณ ์š”? ๊ฐ„๋‹จํžˆ ๋งํ•ด์„œ, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์„ค์ •์„ ์™ธ๋ถ€์—์„œ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ๊ธฐ๋Šฅ์ด์—์š”.

๐ŸŽฏ Externalized Configuration์˜ ํ•ต์‹ฌ ํฌ์ธํŠธ:

  • ์ฝ”๋“œ ๋ณ€๊ฒฝ ์—†์ด ์„ค์ • ๋ณ€๊ฒฝ ๊ฐ€๋Šฅ
  • ํ™˜๊ฒฝ๋ณ„๋กœ ๋‹ค๋ฅธ ์„ค์ • ์ ์šฉ ์‰ฌ์›€
  • ๋ณด์•ˆ์— ๋ฏผ๊ฐํ•œ ์ •๋ณด ๋ถ„๋ฆฌ ๊ฐ€๋Šฅ

์ด๊ฒŒ ์™œ ์ค‘์š”ํ•˜๋ƒ๊ณ ์š”? ์˜ˆ๋ฅผ ๋“ค์–ด๋ณผ๊ฒŒ์š”. ์—ฌ๋Ÿฌ๋ถ„์ด ์ดˆํŠน๊ธ‰ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋˜์–ด์„œ ์—„์ฒญ๋‚œ ์„œ๋น„์Šค๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค๊ณ  ํ•ด๋ด์š”. ๋กœ์ปฌ์—์„œ ๊ฐœ๋ฐœํ•  ๋•Œ๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ฃผ์†Œ๊ฐ€ "localhost"์˜€๋Š”๋ฐ, ์‹ค์ œ ์„œ๋ฒ„์—์„œ๋Š” "super-secure-db.company.com"์ด์—์š”. ์ด๋Ÿด ๋•Œ ์ฝ”๋“œ๋ฅผ ์ผ์ผ์ด ์ˆ˜์ •ํ•˜๊ณ  ๋‹ค์‹œ ๋นŒ๋“œํ•ด์•ผ ํ•œ๋‹ค๋ฉด? ๐Ÿ˜ซ ์ƒ๊ฐ๋งŒ ํ•ด๋„ ๋”์ฐํ•˜์ฃ ?

๋ฐ”๋กœ ์ด๋Ÿฐ ์ƒํ™ฉ์—์„œ Externalized Configuration์ด ๋น›์„ ๋ฐœํ•˜๋Š” ๊ฑฐ์˜ˆ์š”! ์„ค์ •๋งŒ ๋ฐ”๊พธ๋ฉด ๋! ์ฝ”๋“œ ํ•œ ์ค„ ์•ˆ ๊ฑด๋“œ๋ฆฌ๊ณ ๋„ ํ™˜๊ฒฝ์— ๋งž๋Š” ์„ค์ •์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค. ๐Ÿ‘

2. Spring Boot์—์„œ ์„ค์ • ํŒŒ์ผ ์‚ฌ์šฉํ•˜๊ธฐ ๐Ÿ“

์ž, ์ด์ œ ๋ณธ๊ฒฉ์ ์œผ๋กœ Spring Boot์—์„œ ์–ด๋–ป๊ฒŒ ์™ธ๋ถ€ ์„ค์ •์„ ์‚ฌ์šฉํ•˜๋Š”์ง€ ์•Œ์•„๋ณผ๊นŒ์š”? Spring Boot๋Š” ์ •๋ง ๋˜‘๋˜‘ํ•ด์„œ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์œผ๋กœ ์„ค์ •์„ ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์žˆ์–ด์š”. ๊ทธ์ค‘์—์„œ๋„ ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉ๋˜๋Š” ๋ฐฉ๋ฒ•์€ ๋ฐ”๋กœ properties ํŒŒ์ผ๊ณผ YAML ํŒŒ์ผ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฑฐ์˜ˆ์š”.

2.1 Properties ํŒŒ์ผ ์‚ฌ์šฉํ•˜๊ธฐ ๐Ÿ—‚๏ธ

properties ํŒŒ์ผ์€ ๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ ์„ค์ • ํŒŒ์ผ ํ˜•์‹์ด์—์š”. ํ‚ค-๊ฐ’ ์Œ์œผ๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ์ฃ . ์˜ˆ๋ฅผ ๋“ค์–ด๋ณผ๊นŒ์š”?


# application.properties
server.port=8080
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=password

์ด๋ ‡๊ฒŒ ์ž‘์„ฑ๋œ properties ํŒŒ์ผ์„ src/main/resources ๋””๋ ‰ํ† ๋ฆฌ์— ๋„ฃ์œผ๋ฉด Spring Boot๊ฐ€ ์ž๋™์œผ๋กœ ์ฝ์–ด๋“ค์—ฌ์š”. ์—„์ฒญ ํŽธํ•˜์ฃ ? ๐Ÿ˜Ž

2.2 YAML ํŒŒ์ผ ์‚ฌ์šฉํ•˜๊ธฐ ๐ŸŒˆ

YAML ํŒŒ์ผ์€ properties ํŒŒ์ผ๋ณด๋‹ค ์ข€ ๋” ๊ตฌ์กฐ์ ์ด๊ณ  ๊ฐ€๋…์„ฑ์ด ์ข‹์•„์š”. ๊ฐ™์€ ์„ค์ •์„ YAML๋กœ ์ž‘์„ฑํ•˜๋ฉด ์ด๋ ‡๊ฒŒ ๋ฉ๋‹ˆ๋‹ค:


# application.yml
server:
  port: 8080
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mydb
    username: root
    password: password

์–ด๋•Œ์š”? ๋ญ”๊ฐ€ ๋” ๊น”๋”ํ•ด ๋ณด์ด์ง€ ์•Š๋‚˜์š”? ํŠนํžˆ ๊ณ„์ธต ๊ตฌ์กฐ๊ฐ€ ์žˆ๋Š” ์„ค์ •์„ ์ž‘์„ฑํ•  ๋•Œ๋Š” YAML์ด ํ›จ์”ฌ ๋ณด๊ธฐ ์ข‹๋‹ต๋‹ˆ๋‹ค. ๐Ÿ‘€

๐Ÿ’ก ๊ฟ€ํŒ: properties ํŒŒ์ผ๊ณผ YAML ํŒŒ์ผ ์ค‘ ์–ด๋–ค ๊ฑธ ์‚ฌ์šฉํ• ์ง€ ๊ณ ๋ฏผ๋œ๋‹ค๊ณ ์š”? ๊ฑฑ์ • ๋งˆ์„ธ์š”! Spring Boot๋Š” ๋‘˜ ๋‹ค ์ง€์›ํ•˜๋‹ˆ๊นŒ ์—ฌ๋Ÿฌ๋ถ„์˜ ์ทจํ–ฅ๋Œ€๋กœ ์„ ํƒํ•˜๋ฉด ๋ผ์š”. ๊ฐœ์ธ์ ์œผ๋กœ๋Š” YAML์„ ์ถ”์ฒœํ•ฉ๋‹ˆ๋‹ค. ์™œ๋ƒ๊ณ ์š”? ๋” ์˜ˆ์˜๋‹ˆ๊นŒ์š”! ใ…‹ใ…‹ใ…‹

3. ํ”„๋กœํ•„(Profile)๋กœ ํ™˜๊ฒฝ๋ณ„ ์„ค์ • ๊ด€๋ฆฌํ•˜๊ธฐ ๐ŸŒ

์—ฌ๋Ÿฌ๋ถ„, ๊ฐœ๋ฐœํ•  ๋•Œ ๋กœ์ปฌ, ๊ฐœ๋ฐœ ์„œ๋ฒ„, ์Šคํ…Œ์ด์ง• ์„œ๋ฒ„, ํ”„๋กœ๋•์…˜ ์„œ๋ฒ„... ์ด๋ ‡๊ฒŒ ์—ฌ๋Ÿฌ ํ™˜๊ฒฝ์„ ์‚ฌ์šฉํ•˜์‹œ์ฃ ? ๊ฐ ํ™˜๊ฒฝ๋งˆ๋‹ค ์„ค์ •์ด ๋‹ค๋ฅผ ํ…๋ฐ, ์ด๊ฑธ ์–ด๋–ป๊ฒŒ ๊ด€๋ฆฌํ•˜๋ฉด ์ข‹์„๊นŒ์š”? ๋ฐ”๋กœ ์ด๋•Œ Spring Boot์˜ ํ”„๋กœํ•„(Profile) ๊ธฐ๋Šฅ์ด ๋น›์„ ๋ฐœํ•ฉ๋‹ˆ๋‹ค! โœจ

3.1 ํ”„๋กœํ•„์ด๋ž€? ๐ŸŽญ

ํ”„๋กœํ•„์€ ๊ฐ„๋‹จํžˆ ๋งํ•ด์„œ ํŠน์ • ํ™˜๊ฒฝ์— ๋Œ€ํ•œ ์„ค์ • ๋ฌถ์Œ์ด์—์š”. ์˜ˆ๋ฅผ ๋“ค์–ด, ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์šฉ ํ”„๋กœํ•„, ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ์šฉ ํ”„๋กœํ•„, ์šด์˜ ํ™˜๊ฒฝ์šฉ ํ”„๋กœํ•„ ๋“ฑ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์ฃ . ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํ™˜๊ฒฝ๋ณ„๋กœ ๋‹ค๋ฅธ ์„ค์ •์„ ์‰ฝ๊ฒŒ ์ ์šฉํ•  ์ˆ˜ ์žˆ์–ด์š”.

3.2 ํ”„๋กœํ•„ ์„ค์ • ํŒŒ์ผ ๋งŒ๋“ค๊ธฐ ๐Ÿ“

ํ”„๋กœํ•„๋ณ„ ์„ค์ • ํŒŒ์ผ์€ ์ด๋ ‡๊ฒŒ ๋งŒ๋“ค์–ด์š”:

  • application-dev.properties (๋˜๋Š” application-dev.yml): ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ์„ค์ •
  • application-test.properties (๋˜๋Š” application-test.yml): ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ ์„ค์ •
  • application-prod.properties (๋˜๋Š” application-prod.yml): ์šด์˜ ํ™˜๊ฒฝ ์„ค์ •

๊ฐ ํŒŒ์ผ์—๋Š” ํ•ด๋‹น ํ™˜๊ฒฝ์— ๋งž๋Š” ์„ค์ •์„ ๋„ฃ์œผ๋ฉด ๋ผ์š”. ์˜ˆ๋ฅผ ๋“ค์–ด๋ณผ๊นŒ์š”?


# application-dev.yml
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/devdb
    username: devuser
    password: devpass

# application-prod.yml
spring:
  datasource:
    url: jdbc:mysql://prod-server:3306/proddb
    username: produser
    password: supersecret

3.3 ํ”„๋กœํ•„ ํ™œ์„ฑํ™”ํ•˜๊ธฐ ๐Ÿš€

์ž, ์ด์ œ ํ”„๋กœํ•„์„ ์–ด๋–ป๊ฒŒ ํ™œ์„ฑํ™”ํ• ๊นŒ์š”? ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ์–ด์š”:

  1. application.properties (๋˜๋Š” application.yml)์—์„œ ์„ค์ •:
    spring.profiles.active=dev
  2. ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋กœ ์„ค์ •:
    export SPRING_PROFILES_ACTIVE=prod
  3. Java ๋ช…๋ น์–ด๋กœ ์‹คํ–‰ํ•  ๋•Œ ์„ค์ •:
    java -jar myapp.jar --spring.profiles.active=test

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํ•ด๋‹น ํ”„๋กœํ•„์˜ ์„ค์ •์ด ์ ์šฉ๋˜์–ด ์‹คํ–‰๋ผ์š”. ์™„์ „ ์‰ฝ์ฃ ? ๐Ÿ˜‰

โš ๏ธ ์ฃผ์˜์‚ฌํ•ญ: ํ”„๋กœํ•„์„ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ๋ณด์•ˆ์— ์ฃผ์˜ํ•ด์•ผ ํ•ด์š”. ํŠนํžˆ ์šด์˜ ํ™˜๊ฒฝ์˜ ์ค‘์š”ํ•œ ์ •๋ณด(DB ๋น„๋ฐ€๋ฒˆํ˜ธ ๊ฐ™์€ ๊ฒƒ๋“ค)๋Š” ์ ˆ๋Œ€ Git ๊ฐ™์€ ๋ฒ„์ „ ๊ด€๋ฆฌ ์‹œ์Šคํ…œ์— ์˜ฌ๋ฆฌ๋ฉด ์•ˆ ๋ผ์š”! ์ด๋Ÿฐ ์ •๋ณด๋Š” ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋‚˜ ๋ณ„๋„์˜ ์•ˆ์ „ํ•œ ์ €์žฅ์†Œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ต๋‹ˆ๋‹ค.

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

4. @Value์™€ @ConfigurationProperties ์‚ฌ์šฉํ•˜๊ธฐ ๐ŸŽฏ

์ž, ์ด์ œ ์„ค์ • ํŒŒ์ผ์„ ๋งŒ๋“ค์—ˆ์œผ๋‹ˆ ์ด๊ฑธ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•˜๋Š”์ง€ ์•Œ์•„๋ณผ๊นŒ์š”? Spring Boot์—์„œ๋Š” @Value์™€ @ConfigurationProperties๋ผ๋Š” ๋‘ ๊ฐ€์ง€ ์ฃผ์š” ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•ด์š”. ์ด ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์˜ ์ฐจ์ด์ ๊ณผ ์‚ฌ์šฉ๋ฒ•์„ ์ž์„ธํžˆ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค!

4.1 @Value ์• ๋…ธํ…Œ์ด์…˜ ์‚ฌ์šฉํ•˜๊ธฐ ๐Ÿ’‰

@Value ์• ๋…ธํ…Œ์ด์…˜์€ ๊ฐ„๋‹จํ•˜๊ฒŒ ์„ค์ • ๊ฐ’์„ ์ฃผ์ž…๋ฐ›์„ ๋•Œ ์‚ฌ์šฉํ•ด์š”. ํŠน์ • ํ•„๋“œ์— ์ง์ ‘ ๊ฐ’์„ ์ฃผ์ž…ํ•  ์ˆ˜ ์žˆ์ฃ . ์‚ฌ์šฉ๋ฒ•์€ ์ด๋ ‡์Šต๋‹ˆ๋‹ค:


import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class MyService {

    @Value("${server.port}")
    private int serverPort;

    @Value("${spring.datasource.url}")
    private String databaseUrl;

    // ๋ฉ”์„œ๋“œ๋“ค...
}

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด application.properties ๋˜๋Š” application.yml์— ์ •์˜๋œ server.port์™€ spring.datasource.url ๊ฐ’์ด ๊ฐ๊ฐ serverPort์™€ databaseUrl ํ•„๋“œ์— ์ฃผ์ž…๋ผ์š”.

@Value์˜ ์žฅ์ ์€ ๊ฐ„๋‹จํ•˜๊ณ  ์ง๊ด€์ ์ด๋ผ๋Š” ๊ฑฐ์˜ˆ์š”. ํ•˜์ง€๋งŒ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๊ด€๋ จ๋œ ์„ค์ •์„ ๋ฌถ์–ด์„œ ๊ด€๋ฆฌํ•˜๊ธฐ๋Š” ์ข€ ๋ถˆํŽธํ•˜์ฃ .

4.2 @ConfigurationProperties ์‚ฌ์šฉํ•˜๊ธฐ ๐Ÿ“ฆ

@ConfigurationProperties๋Š” ์—ฌ๋Ÿฌ ์„ค์ •์„ ํ•˜๋‚˜์˜ ํด๋ž˜์Šค๋กœ ๋ฌถ์–ด์„œ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค˜์š”. ํŠนํžˆ ๊ณ„์ธต ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง„ ์„ค์ •์„ ๋‹ค๋ฃฐ ๋•Œ ์•„์ฃผ ์œ ์šฉํ•˜๋‹ต๋‹ˆ๋‹ค.


import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "myapp.datasource")
public class DatabaseProperties {

    private String url;
    private String username;
    private String password;

    // getter์™€ setter ๋ฉ”์„œ๋“œ๋“ค...
}

์ด๋ ‡๊ฒŒ ์„ค์ •ํ•˜๊ณ  application.yml์— ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•˜๋ฉด:


myapp:
  datasource:
    url: jdbc:mysql://localhost:3306/mydb
    username: user
    password: pass

Spring Boot๊ฐ€ ์ž๋™์œผ๋กœ DatabaseProperties ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๊ฐ’์„ ์ฑ„์›Œ์ค˜์š”. ์™„์ „ ํŽธํ•˜์ฃ ? ๐Ÿ˜Ž

๐ŸŒŸ @ConfigurationProperties์˜ ์žฅ์ :

  • ๊ด€๋ จ๋œ ์„ค์ •์„ ํ•˜๋‚˜์˜ ํด๋ž˜์Šค๋กœ ๋ฌถ์„ ์ˆ˜ ์žˆ์–ด์š”.
  • ํƒ€์ž… ์•ˆ์ „์„ฑ์„ ๋ณด์žฅํ•ด์š”. (์˜ˆ: int๋กœ ์„ ์–ธ๋œ ํ•„๋“œ์— ๋ฌธ์ž์—ด์ด ๋“ค์–ด์˜ค๋ฉด ์˜ค๋ฅ˜ ๋ฐœ์ƒ)
  • IDE์˜ ์ž๋™ ์™„์„ฑ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์š”. (๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ํ”„๋กœ์„ธ์„œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด)

4.3 @Value vs @ConfigurationProperties: ์–ด๋–ค ๊ฑธ ์‚ฌ์šฉํ•ด์•ผ ํ• ๊นŒ? ๐Ÿค”

๋‘ ๋ฐฉ๋ฒ• ๋‹ค ์žฅ๋‹จ์ ์ด ์žˆ์–ด์š”. ๊ฐ„๋‹จํžˆ ์ •๋ฆฌํ•ด๋ณผ๊ฒŒ์š”:

  • @Value: ๊ฐ„๋‹จํ•œ ์„ค์ • ๊ฐ’ ํ•˜๋‚˜๋ฅผ ์ฃผ์ž…๋ฐ›์„ ๋•Œ ์ข‹์•„์š”. ์ฝ”๋“œ๊ฐ€ ๊ฐ„๊ฒฐํ•ด์ง€์ฃ .
  • @ConfigurationProperties: ๊ด€๋ จ๋œ ์—ฌ๋Ÿฌ ์„ค์ •์„ ๋ฌถ์–ด์„œ ๊ด€๋ฆฌํ•  ๋•Œ, ๋˜๋Š” ๊ณ„์ธต ๊ตฌ์กฐ๊ฐ€ ์žˆ๋Š” ๋ณต์žกํ•œ ์„ค์ •์„ ๋‹ค๋ฃฐ ๋•Œ ์ข‹์•„์š”.

๊ฐœ์ธ์ ์ธ ์˜๊ฒฌ์„ ๋งํ•˜์ž๋ฉด, ๊ฐ€๋Šฅํ•˜๋ฉด @ConfigurationProperties๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฑธ ์ถ”์ฒœํ•ด์š”. ์™œ๋ƒ๊ณ ์š”? ๋‚˜์ค‘์— ์„ค์ •์ด ๋ณต์žกํ•ด์ ธ๋„ ์‰ฝ๊ฒŒ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฑฐ๋“ ์š”. ๊ทธ๋ฆฌ๊ณ  ๋ฌด์—‡๋ณด๋‹ค ํƒ€์ž… ์•ˆ์ „์„ฑ์ด ๋ณด์žฅ๋˜๋‹ˆ๊นŒ ์‹ค์ˆ˜ํ•  ํ™•๋ฅ ์ด ์ค„์–ด๋“ค์ฃ ! ๐Ÿ‘

5. ํ™˜๊ฒฝ ๋ณ€์ˆ˜์™€ ์ปค๋งจ๋“œ ๋ผ์ธ ์ธ์ž ์‚ฌ์šฉํ•˜๊ธฐ ๐Ÿ–ฅ๏ธ

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

5.1 ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์‚ฌ์šฉํ•˜๊ธฐ ๐ŸŒ

ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋Š” ์šด์˜ ์ฒด์ œ ๋ ˆ๋ฒจ์—์„œ ์„ค์ •ํ•˜๋Š” ๊ฐ’์ด์—์š”. ํŠนํžˆ ๋ฏผ๊ฐํ•œ ์ •๋ณด(์˜ˆ: ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋น„๋ฐ€๋ฒˆํ˜ธ)๋ฅผ ๊ด€๋ฆฌํ•  ๋•Œ ์•„์ฃผ ์œ ์šฉํ•˜์ฃ .

์˜ˆ๋ฅผ ๋“ค์–ด, ๋ฆฌ๋ˆ…์Šค๋‚˜ macOS์—์„œ๋Š” ์ด๋ ‡๊ฒŒ ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์–ด์š”:


export SPRING_DATASOURCE_URL=jdbc:mysql://localhost:3306/mydb
export SPRING_DATASOURCE_USERNAME=root
export SPRING_DATASOURCE_PASSWORD=supersecret

์œˆ๋„์šฐ์—์„œ๋Š” ์ด๋ ‡๊ฒŒ ํ•ด์š”:


set SPRING_DATASOURCE_URL=jdbc:mysql://localhost:3306/mydb
set SPRING_DATASOURCE_USERNAME=root
set SPRING_DATASOURCE_PASSWORD=supersecret

์ด๋ ‡๊ฒŒ ์„ค์ •ํ•œ ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋Š” Spring Boot๊ฐ€ ์ž๋™์œผ๋กœ ์ฝ์–ด๋“ค์—ฌ์š”. ์‹ ๊ธฐํ•˜์ฃ ? ๐Ÿ˜ฒ

5.2 ์ปค๋งจ๋“œ ๋ผ์ธ ์ธ์ž ์‚ฌ์šฉํ•˜๊ธฐ โŒจ๏ธ

์ปค๋งจ๋“œ ๋ผ์ธ ์ธ์ž๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‹คํ–‰ํ•  ๋•Œ ์ง์ ‘ ์„ค์ • ๊ฐ’์„ ์ „๋‹ฌํ•˜๋Š” ๋ฐฉ๋ฒ•์ด์—์š”. ์ด๋ ‡๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ฃ :


java -jar myapp.jar --server.port=8080 --spring.datasource.url=jdbc:mysql://localhost:3306/mydb

์ด ๋ฐฉ๋ฒ•์€ ํŠนํžˆ Docker ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์œ ์šฉํ•ด์š”. ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์‹คํ–‰ํ•  ๋•Œ๋งˆ๋‹ค ๋‹ค๋ฅธ ์„ค์ •์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ๊ฑฐ๋“ ์š”.

๐Ÿ”‘ ๋ณด์•ˆ ํŒ: ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋‚˜ ์ปค๋งจ๋“œ ๋ผ์ธ ์ธ์ž๋กœ ์ „๋‹ฌ๋œ ๊ฐ’์€ ์„ค์ • ํŒŒ์ผ์˜ ๊ฐ’๋ณด๋‹ค ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋†’์•„์š”. ๋”ฐ๋ผ์„œ ์ค‘์š”ํ•œ ์ •๋ณด๋Š” ์ด ๋ฐฉ๋ฒ•์œผ๋กœ ์ „๋‹ฌํ•˜๊ณ , ์„ค์ • ํŒŒ์ผ์—๋Š” ๊ธฐ๋ณธ๊ฐ’๋งŒ ๋„ฃ์–ด๋‘๋Š” ๊ฒƒ์ด ์ข‹๋‹ต๋‹ˆ๋‹ค!

5.3 ์šฐ์„ ์ˆœ์œ„ ์ดํ•ดํ•˜๊ธฐ ๐Ÿ†

Spring Boot๋Š” ์—ฌ๋Ÿฌ ๊ณณ์—์„œ ์„ค์ •์„ ์ฝ์–ด์˜ฌ ์ˆ˜ ์žˆ์–ด์š”. ๊ทธ๋Ÿผ ๊ฐ™์€ ์„ค์ •์ด ์—ฌ๋Ÿฌ ๊ณณ์— ์žˆ๋‹ค๋ฉด ์–ด๋–ค ๊ฐ’์„ ์‚ฌ์šฉํ• ๊นŒ์š”? ๋ฐ”๋กœ ์šฐ์„ ์ˆœ์œ„์— ๋”ฐ๋ผ ๊ฒฐ์ •๋ผ์š”!

๋Œ€๋žต์ ์ธ ์šฐ์„ ์ˆœ์œ„๋Š” ์ด๋ ‡๋‹ต๋‹ˆ๋‹ค (๋†’์€ ์ˆœ์„œ๋ถ€ํ„ฐ):

  1. ์ปค๋งจ๋“œ ๋ผ์ธ ์ธ์ž
  2. Java ์‹œ์Šคํ…œ ํ”„๋กœํผํ‹ฐ
  3. OS ํ™˜๊ฒฝ ๋ณ€์ˆ˜
  4. application.properties ๋˜๋Š” application.yml (์™ธ๋ถ€)
  5. application.properties ๋˜๋Š” application.yml (ํŒจํ‚ค์ง€ ๋‚ด๋ถ€)

์ด ์šฐ์„ ์ˆœ์œ„๋ฅผ ์ž˜ ์ดํ•ดํ•˜๊ณ  ์žˆ์œผ๋ฉด, ์„ค์ • ๊ด€๋ฆฌ๊ฐ€ ํ•œ๊ฒฐ ์ˆ˜์›”ํ•ด์งˆ ๊ฑฐ์˜ˆ์š”. ์˜ˆ๋ฅผ ๋“ค์–ด, ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์—์„œ๋Š” application-dev.yml์„ ์‚ฌ์šฉํ•˜๊ณ , ์šด์˜ ํ™˜๊ฒฝ์—์„œ๋Š” ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋กœ ์ค‘์š” ์ •๋ณด๋ฅผ ๋ฎ์–ด์“ฐ๋Š” ์‹์œผ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์ฃ .

์—ฌ๊ธฐ์„œ ์ž ๊น! ์ด๋Ÿฐ ์„ค์ • ๊ด€๋ฆฌ ๋…ธํ•˜์šฐ๋ฅผ ๋‹ค๋ฅธ ๊ฐœ๋ฐœ์ž๋“ค๊ณผ ๊ณต์œ ํ•˜๊ณ  ์‹ถ์ง€ ์•Š์œผ์„ธ์š”? ์žฌ๋Šฅ๋„ท์—์„œ ์—ฌ๋Ÿฌ๋ถ„์˜ ์ง€์‹์„ ๋‚˜๋ˆ„์–ด๋ณด๋Š” ๊ฑด ์–ด๋–จ๊นŒ์š”? ๋‹ค๋ฅธ ๊ฐœ๋ฐœ์ž๋“ค์—๊ฒŒ ๋„์›€์ด ๋˜๋ฉด์„œ, ์—ฌ๋Ÿฌ๋ถ„๋„ ์ƒˆ๋กœ์šด ์ธ์‚ฌ์ดํŠธ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์„ ๊ฑฐ์˜ˆ์š”! ๐Ÿ’ก

6. ์„ค์ • ๊ฐ’ ์•”ํ˜ธํ™”ํ•˜๊ธฐ ๐Ÿ”

์ž, ์ด์ œ ์„ค์ • ๊ด€๋ฆฌ์˜ ๊ฝƒ์ด๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๋Š” ์„ค์ • ๊ฐ’ ์•”ํ˜ธํ™”์— ๋Œ€ํ•ด ์•Œ์•„๋ณผ๊นŒ์š”? ๋ณด์•ˆ์ด ์ค‘์š”ํ•œ ํ˜„๋Œ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ๋Š” ํ•„์ˆ˜๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ์ฃ !

6.1 ์™œ ์„ค์ • ๊ฐ’์„ ์•”ํ˜ธํ™”ํ•ด์•ผ ํ• ๊นŒ์š”? ๐Ÿค”

์—ฌ๋Ÿฌ๋ถ„, ์ƒ์ƒํ•ด๋ณด์„ธ์š”. ์—ฌ๋Ÿฌ๋ถ„์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„ค์ • ํŒŒ์ผ์— ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋น„๋ฐ€๋ฒˆํ˜ธ, API ํ‚ค, ์•”ํ˜ธํ™” ํ‚ค ๋“ฑ์ด ํ‰๋ฌธ์œผ๋กœ ์ ํ˜€์žˆ๋‹ค๋ฉด? ๐Ÿ˜ฑ ๋ˆ„๊ตฐ๊ฐ€ ์ด ํŒŒ์ผ์„ ๋ณด๊ฒŒ ๋œ๋‹ค๋ฉด ๋Œ€์ฐธ์‚ฌ๊ฐ€ ์ผ์–ด๋‚  ์ˆ˜ ์žˆ๊ฒ ์ฃ ?

๋ฐ”๋กœ ์ด๋Ÿฐ ์ด์œ  ๋•Œ๋ฌธ์— ์ค‘์š”ํ•œ ์„ค์ • ๊ฐ’์€ ๋ฐ˜๋“œ์‹œ ์•”ํ˜ธํ™”ํ•ด์•ผ ํ•ด์š”. Spring Boot์—์„œ๋Š” ์ด๋ฅผ ์œ„ํ•œ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•˜๋Š”๋ฐ, ๊ทธ ์ค‘ ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉ๋˜๋Š” ๋ฐฉ๋ฒ•์ด ๋ฐ”๋กœ Jasypt(Java Simplified Encryption)์˜ˆ์š”.

6.2 Jasypt ์„ค์ •ํ•˜๊ธฐ ๐Ÿ› ๏ธ

Jasypt๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋จผ์ € ์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ด์š”. build.gradle ํŒŒ์ผ์— ๋‹ค์Œ ๋‚ด์šฉ์„ ์ถ”๊ฐ€ํ•ด์ฃผ์„ธ์š”:


implementation 'com.github.ulisesbocchio:jasypt-spring-boot-starter:3.0.3'

๊ทธ๋ฆฌ๊ณ  application.yml ํŒŒ์ผ์— ๋‹ค์Œ๊ณผ ๊ฐ™์ด Jasypt ์„ค์ •์„ ์ถ”๊ฐ€ํ•ด์ค๋‹ˆ๋‹ค:


jasypt:
  encryptor:
    password: ${JASYPT_ENCRYPTOR_PASSWORD}

์—ฌ๊ธฐ์„œ ${JASYPT_ENCRYPTOR_PASSWORD}๋Š” ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋กœ ์„ค์ •ํ•  ์•”ํ˜ธํ™” ํ‚ค์˜ˆ์š”. ์ด ํ‚ค๋Š” ์ ˆ๋Œ€๋กœ ์†Œ์Šค ์ฝ”๋“œ๋‚˜ ์„ค์ • ํŒŒ์ผ์— ์ง์ ‘ ๋„ฃ์œผ๋ฉด ์•ˆ ๋ผ์š”! ๊ผญ ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋กœ ๊ด€๋ฆฌํ•ด์ฃผ์„ธ์š”.

6.3 ์„ค์ • ๊ฐ’ ์•”ํ˜ธํ™”ํ•˜๊ธฐ ๐Ÿ”’

์ž, ์ด์ œ ์ค‘์š”ํ•œ ์„ค์ • ๊ฐ’์„ ์•”ํ˜ธํ™”ํ•ด๋ณผ๊นŒ์š”? Jasypt๋Š” ๋ช…๋ น์ค„ ๋„๊ตฌ๋ฅผ ์ œ๊ณตํ•˜์ง€๋งŒ, ๊ฐ„๋‹จํžˆ Java ์ฝ”๋“œ๋กœ๋„ ์•”ํ˜ธํ™”ํ•  ์ˆ˜ ์žˆ์–ด์š”. ์˜ˆ๋ฅผ ๋“ค์–ด:


import org.jasypt.encryption.pbe.PooledPBEStringEncryptor;
import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig;

public class PasswordEncryptor {
    public static void main(String[] args) {
        PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
        SimpleStringPBEConfig config = new SimpleStringPBEConfig();
        config.setPassword("yourEncryptionKey"); // ์‹ค์ œ๋กœ๋Š” ํ™˜๊ฒฝ ๋ณ€์ˆ˜์—์„œ ๊ฐ€์ ธ์™€์•ผ ํ•ด์š”!
        config.setAlgorithm("PBEWithMD5AndDES");
        config.setKeyObtentionIterations("1000");
        config.setPoolSize("1");
        config.setProviderName("SunJCE");
        config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
        config.setStringOutputType("base64");
        encryptor.setConfig(config);

        String plainText = "superSecretPassword";
        String encryptedText = encryptor.encrypt(plainText);
        System.out.println("Encrypted: " + encryptedText);
    }
}

์ด๋ ‡๊ฒŒ ์•”ํ˜ธํ™”๋œ ๊ฐ’์„ ์–ป์„ ์ˆ˜ ์žˆ์–ด์š”. ์ด์ œ ์ด ๊ฐ’์„ ์„ค์ • ํŒŒ์ผ์— ๋„ฃ์„ ๋•Œ๋Š” ENC()๋กœ ๊ฐ์‹ธ์ฃผ๋ฉด ๋ผ์š”:


spring:
  datasource:
    password: ENC(์—ฌ๊ธฐ์— ์•”ํ˜ธํ™”๋œ ๊ฐ’์„ ๋„ฃ์–ด์ฃผ์„ธ์š”)

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด Spring Boot๊ฐ€ ์ž๋™์œผ๋กœ ์ด ๊ฐ’์„ ๋ณตํ˜ธํ™”ํ•ด์„œ ์‚ฌ์šฉํ•ด์š”. ์™„์ „ ์‹ ๊ธฐํ•˜์ฃ ? ๐Ÿ˜Ž

๐Ÿ’ก Pro Tip: ์•”ํ˜ธํ™” ํ‚ค๋Š” ์ ˆ๋Œ€๋กœ ์†Œ์Šค ์ฝ”๋“œ์— ํ•˜๋“œ์ฝ”๋”ฉํ•˜๋ฉด ์•ˆ ๋ผ์š”! ์œ„์˜ ์˜ˆ์ œ๋Š” ์„ค๋ช…์„ ์œ„ํ•œ ๊ฒƒ์ผ ๋ฟ์ด์—์š”. ์‹ค์ œ๋กœ๋Š” ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋‚˜ ์•ˆ์ „ํ•œ ํ‚ค ๊ด€๋ฆฌ ์‹œ์Šคํ…œ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•ด์š”.

6.4 ์•”ํ˜ธํ™”๋œ ๊ฐ’ ์‚ฌ์šฉํ•˜๊ธฐ ๐Ÿ”“

์•”ํ˜ธํ™”๋œ ๊ฐ’์„ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ํŠน๋ณ„ํžˆ ํ•  ์ผ์ด ์—†์–ด์š”. Spring Boot๊ฐ€ ์•Œ์•„์„œ ๋ณตํ˜ธํ™”ํ•ด์„œ ์‚ฌ์šฉํ•˜๊ฑฐ๋“ ์š”. ์˜ˆ๋ฅผ ๋“ค์–ด:


@Value("${spring.datasource.password}")
private String databasePassword;

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด databasePassword ๋ณ€์ˆ˜์—๋Š” ๋ณตํ˜ธํ™”๋œ ์‹ค์ œ ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ๋“ค์–ด๊ฐ€์š”. ํŽธํ•˜์ฃ ? ๐Ÿ˜‰

์•”ํ˜ธํ™”๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์„ค์ • ํŒŒ์ผ์„ ๋ฒ„์ „ ๊ด€ ๋ฆฌ ์‹œ์Šคํ…œ์— ์•ˆ์ „ํ•˜๊ฒŒ ์˜ฌ๋ฆด ์ˆ˜ ์žˆ๊ณ , ํŒ€์›๋“ค๊ณผ ๊ณต์œ ํ•  ๋•Œ๋„ ๊ฑฑ์ •์ด ์—†์–ด์ ธ์š”. ๋ฌผ๋ก , ์•”ํ˜ธํ™” ํ‚ค ์ž์ฒด๋Š” ์ ˆ๋Œ€๋กœ ๊ณต์œ ํ•˜๋ฉด ์•ˆ ๋˜๊ฒ ์ฃ ?

7. ์„ค์ • ๋ฆฌํ”„๋ ˆ์‹œํ•˜๊ธฐ ๐Ÿ”„

์ž, ์ด์ œ ์ •๋ง ๊ณ ๊ธ‰ ๊ธฐ์ˆ ์„ ์•Œ์•„๋ณผ ์ฐจ๋ก€์˜ˆ์š”. ๋ฐ”๋กœ ๋Ÿฐํƒ€์ž„์— ์„ค์ •์„ ๋ฆฌํ”„๋ ˆ์‹œํ•˜๋Š” ๋ฐฉ๋ฒ•์ด์—์š”. ์ด๊ฒŒ ๋ฌด์Šจ ๋ง์ด๋ƒ๊ณ ์š”? ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์žฌ์‹œ์ž‘ํ•˜์ง€ ์•Š๊ณ ๋„ ์„ค์ •์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฑฐ์˜ˆ์š”! ๐Ÿ˜ฒ

7.1 @RefreshScope ์‚ฌ์šฉํ•˜๊ธฐ ๐ŸŽฏ

Spring Cloud ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด @RefreshScope ์• ๋…ธํ…Œ์ด์…˜์„ ํ†ตํ•ด ํŠน์ • ๋นˆ์˜ ์„ค์ •์„ ๋™์ ์œผ๋กœ ๋ฆฌํ”„๋ ˆ์‹œํ•  ์ˆ˜ ์žˆ์–ด์š”. ๋จผ์ € ์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•ด๋ณผ๊นŒ์š”?


implementation 'org.springframework.cloud:spring-cloud-starter'

๊ทธ๋ฆฌ๊ณ  ์„ค์ •์„ ๋ฆฌํ”„๋ ˆ์‹œํ•˜๊ณ  ์‹ถ์€ ๋นˆ์— @RefreshScope๋ฅผ ๋ถ™์—ฌ์ฃผ์„ธ์š”:


import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;

@RefreshScope
@Component
public class DatabaseConfig {
    @Value("${spring.datasource.url}")
    private String url;

    // getter, setter...
}

7.2 ์„ค์ • ๋ฆฌํ”„๋ ˆ์‹œ ์—”๋“œํฌ์ธํŠธ ํ™œ์„ฑํ™”ํ•˜๊ธฐ ๐Ÿš€

์ด์ œ ์„ค์ •์„ ๋ฆฌํ”„๋ ˆ์‹œํ•  ์ˆ˜ ์žˆ๋Š” ์—”๋“œํฌ์ธํŠธ๋ฅผ ํ™œ์„ฑํ™”ํ•ด์•ผ ํ•ด์š”. application.yml์— ๋‹ค์Œ ๋‚ด์šฉ์„ ์ถ”๊ฐ€ํ•ด์ฃผ์„ธ์š”:


management:
  endpoints:
    web:
      exposure:
        include: refresh

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด /actuator/refresh ์—”๋“œํฌ์ธํŠธ๊ฐ€ ํ™œ์„ฑํ™”๋ผ์š”.

7.3 ์„ค์ • ๋ฆฌํ”„๋ ˆ์‹œํ•˜๊ธฐ ๐Ÿ”„

์ด์ œ ์„ค์ •์„ ๋ณ€๊ฒฝํ•˜๊ณ  ์‹ถ์„ ๋•Œ๋งˆ๋‹ค ์ด ์—”๋“œํฌ์ธํŠธ๋กœ POST ์š”์ฒญ์„ ๋ณด๋‚ด๋ฉด ๋ผ์š”:


curl -X POST http://localhost:8080/actuator/refresh

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด @RefreshScope๊ฐ€ ๋ถ™์€ ๋นˆ๋“ค์˜ ์„ค์ •์ด ๋ชจ๋‘ ๋ฆฌํ”„๋ ˆ์‹œ๋ผ์š”. ์™„์ „ ์‹ ๊ธฐํ•˜์ฃ ? ๐Ÿ˜Ž

โš ๏ธ ์ฃผ์˜์‚ฌํ•ญ: ์ด ๊ธฐ๋Šฅ์€ ๋งค์šฐ ๊ฐ•๋ ฅํ•˜์ง€๋งŒ, ๋ณด์•ˆ์— ์ฃผ์˜ํ•ด์•ผ ํ•ด์š”. ๋ˆ„๊ตฌ๋‚˜ ์ด ์—”๋“œํฌ์ธํŠธ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ํฐ ๋ฌธ์ œ๊ฐ€ ๋  ์ˆ˜ ์žˆ์ฃ . ๋ฐ˜๋“œ์‹œ ์ ์ ˆํ•œ ๋ณด์•ˆ ์„ค์ •์„ ํ•ด์ฃผ์„ธ์š”!

8. ๋งˆ์น˜๋ฉฐ: ์„ค์ • ๊ด€๋ฆฌ์˜ ๋ฒ ์ŠคํŠธ ํ”„๋ž™ํ‹ฐ์Šค ๐Ÿ†

์ž, ์ด์ œ Spring Boot์˜ Externalized Configuration์— ๋Œ€ํ•ด ๊ฑฐ์˜ ๋ชจ๋“  ๊ฒƒ์„ ๋ฐฐ์› ์–ด์š”! ๋งˆ์ง€๋ง‰์œผ๋กœ, ์„ค์ • ๊ด€๋ฆฌ์˜ ๋ฒ ์ŠคํŠธ ํ”„๋ž™ํ‹ฐ์Šค๋ฅผ ์ •๋ฆฌํ•ด๋ณผ๊นŒ์š”?

  1. ํ™˜๊ฒฝ๋ณ„ ์„ค์ • ๋ถ„๋ฆฌ: ๊ฐœ๋ฐœ, ํ…Œ์ŠคํŠธ, ์šด์˜ ํ™˜๊ฒฝ์˜ ์„ค์ •์„ ๋ช…ํ™•ํžˆ ๋ถ„๋ฆฌํ•˜์„ธ์š”.
  2. ๋ฏผ๊ฐํ•œ ์ •๋ณด ๋ณดํ˜ธ: ๋น„๋ฐ€๋ฒˆํ˜ธ, API ํ‚ค ๋“ฑ์€ ๋ฐ˜๋“œ์‹œ ์•”ํ˜ธํ™”ํ•˜๊ฑฐ๋‚˜ ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋กœ ๊ด€๋ฆฌํ•˜์„ธ์š”.
  3. ๋ฒ„์ „ ๊ด€๋ฆฌ: ์„ค์ • ํŒŒ์ผ๋„ ์†Œ์Šค ์ฝ”๋“œ์™€ ํ•จ๊ป˜ ๋ฒ„์ „ ๊ด€๋ฆฌํ•˜์„ธ์š”. ๋‹จ, ๋ฏผ๊ฐํ•œ ์ •๋ณด๋Š” ์ œ์™ธ!
  4. ๋ฌธ์„œํ™”: ๊ฐ ์„ค์ •์˜ ์˜๋ฏธ์™€ ์‚ฌ์šฉ๋ฒ•์„ ๋ฌธ์„œ๋กœ ๋‚จ๊ธฐ์„ธ์š”. ํŒ€์›๋“ค์—๊ฒŒ ํฐ ๋„์›€์ด ๋  ๊ฑฐ์˜ˆ์š”.
  5. ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ: ๊ฐ€๋Šฅํ•˜๋ฉด ์„ค์ • ๊ฐ’์˜ ์œ ํšจ์„ฑ์„ ๊ฒ€์‚ฌํ•˜๋Š” ๋กœ์ง์„ ์ถ”๊ฐ€ํ•˜์„ธ์š”.
  6. ๊ธฐ๋ณธ๊ฐ’ ์ œ๊ณต: ๋ชจ๋“  ์„ค์ •์— ์ ์ ˆํ•œ ๊ธฐ๋ณธ๊ฐ’์„ ์ œ๊ณตํ•˜์„ธ์š”. ์‹ค์ˆ˜๋กœ ์„ค์ •์„ ๋นผ๋จน์–ด๋„ ๋ฌธ์ œ์—†๊ฒŒ!
  7. ๋กœ๊น…: ์–ด๋–ค ์„ค์ •์ด ์‚ฌ์šฉ๋˜๊ณ  ์žˆ๋Š”์ง€ ๋กœ๊ทธ๋กœ ๋‚จ๊ธฐ์„ธ์š”. ๋ฌธ์ œ ํ•ด๊ฒฐ์— ํฐ ๋„์›€์ด ๋ผ์š”.

์ด๋ ‡๊ฒŒ Spring Boot์˜ Externalized Configuration์— ๋Œ€ํ•ด ๊นŠ์ด ์žˆ๊ฒŒ ์•Œ์•„๋ดค์–ด์š”. ์ด์ œ ์—ฌ๋Ÿฌ๋ถ„์€ ์„ค์ • ๊ด€๋ฆฌ์˜ ๋‹ฌ์ธ์ด ๋˜์—ˆ๋‹ต๋‹ˆ๋‹ค! ๐Ÿ‘‘

๊ทธ๋Ÿฐ๋ฐ ๋ง์ด์—์š”, ์ด๋ ‡๊ฒŒ ๋ฐฐ์šด ์ง€์‹์„ ํ˜ผ์ž๋งŒ ์•Œ๊ณ  ์žˆ๊ธฐ๋Š” ๋„ˆ๋ฌด ์•„๊น์ง€ ์•Š๋‚˜์š”? ์žฌ๋Šฅ๋„ท์—์„œ ์—ฌ๋Ÿฌ๋ถ„์˜ ์ง€์‹์„ ๋‹ค๋ฅธ ๊ฐœ๋ฐœ์ž๋“ค๊ณผ ๋‚˜๋ˆ ๋ณด๋Š” ๊ฑด ์–ด๋–จ๊นŒ์š”? ์—ฌ๋Ÿฌ๋ถ„์˜ ๊ฒฝํ—˜๊ณผ ๋…ธํ•˜์šฐ๋Š” ๋‹ค๋ฅธ ๋ˆ„๊ตฐ๊ฐ€์—๊ฒŒ ํฐ ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์–ด์š”. ๊ทธ๋ฆฌ๊ณ  ๊ฐ€๋ฅด์น˜๋ฉด์„œ ๋ฐฐ์šฐ๋Š” ๊ฒƒ๋„ ๋งŽ๋‹ต๋‹ˆ๋‹ค! ๐Ÿค“

Spring Boot๋กœ ๊ฐœ๋ฐœํ•˜๋ฉด์„œ ๊ถ๊ธˆํ•œ ์ ์ด ์ƒ๊ธฐ๋ฉด ์–ธ์ œ๋“  ๋ฌผ์–ด๋ณด์„ธ์š”. ํ•จ๊ป˜ ์„ฑ์žฅํ•˜๋Š” ๊ฐœ๋ฐœ์ž ์ปค๋ฎค๋‹ˆํ‹ฐ๋ฅผ ๋งŒ๋“ค์–ด๊ฐ€์š”! ํ™”์ดํŒ…! ๐Ÿ’ช

๋Œ“๊ธ€ ์ž‘์„ฑ

์ด ๊ธ€์— ๋Œ€ํ•œ ์—ฌ๋Ÿฌ๋ถ„์˜ ์ƒ๊ฐ์„ ๋“ค๋ ค์ฃผ์„ธ์š”

๋Œ“๊ธ€ 0
๋Œ“๊ธ€์„ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ค‘์ž…๋‹ˆ๋‹ค.

์•„์ง ๋Œ“๊ธ€์ด ์—†์Šต๋‹ˆ๋‹ค.