[06] Externalized Configuration

MIIINยท2021๋…„ 10์›” 2์ผ
0

Spring Boot

๋ชฉ๋ก ๋ณด๊ธฐ
6/9
post-thumbnail

๐ŸŒ ์™ธ๋ถ€ํ™”๋œ ์„ค์ •

Spring Boot๋Š” ์„ค์ •์„ ์™ธ๋ถ€ํ™”ํ•˜์—ฌ ๊ฐ™์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ฝ”๋“œ๊ฐ€ ๋‹ค๋ฅธ ํ™˜๊ฒฝ๋“ค๋กœ ์ž‘๋™๋˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค. Java properties ํŒŒ์ผ, YAML ํŒŒ์ผ, ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ๊ทธ๋ฆฌ๊ณ  ๋ช…๋ น์ค„(Command-line) ์ธ์ˆ˜ ๊ฐ™์€ ๋‹ค์–‘ํ•œ ์™ธ๋ถ€ํ™” ์„ค์ • ์†Œ์Šค๋“ค์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

์†์„ฑ ๊ฐ’๋“ค์€ @Value ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ Bean์œผ๋กœ ์ฃผ์ž…๋˜๊ฑฐ๋‚˜ Spring์˜ Environment ์ถ”์ƒํ™”๋ฅผ ํ†ตํ•˜์—ฌ ์ ‘๊ทผํ•˜๊ฑฐ๋‚˜ @ConfiurationPerperties ์–ด๋…ธํ…Œ์ด์…˜์„ ํ†ตํ•ด ๊ตฌ์กฐํ™”๋œ ๊ฐ์ฒด๋“ค๋กœ ๋ฐ”์ธ๋”ฉ๋  ์ˆ˜ ์žˆ๋‹ค.

Spring Boot๋Š” ๋งค์šฐ ํŠน๋ณ„ํ•œ PropertySource ์ˆœ์„œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉฐ ๊ฐ’๋“ค์˜ ๋ถ„๋ณ„์žˆ๋Š” ์˜ค๋ฒ„๋ผ์ด๋”ฉ์„ ํ—ˆ์šฉํ•œ๋‹ค.
(์šฐ์„  ์ˆœ์œ„๊ฐ€ ๋‚ฎ์„ ์ˆ˜๋ก ๋†’์€ ์ˆœ์œ„์˜ ๊ฐ’์„ ์˜ค๋ฒ„๋ผ์ด๋”ฉ)

์šฐ์„ ์ˆœ์œ„PropertySource
1Devtools ์ „์—ญ ์„ค์ • ๋ณ€์ˆ˜, %HOME/.config/spring-boot ํด๋”
2@TestPropertySource ์–ด๋…ธํ…Œ์ด์…˜
3ํ…Œ์ŠคํŠธ์—์„œ์˜ properties ์†์„ฑ, @SpringBootTest ๋ฐ @...Test ์–ด๋…ธํ…Œ์ด์…˜
4๋ช…๋ น์ค„(Command-line) ์ธ์ˆ˜
5SPRING_APPLICATION_JSON, ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋‚˜ ์‹œ์Šคํ…œ ์†์„ฑ์— ๋‚ด์žฅ๋œ inline JSON
6ServletConfig ์ดˆ๊ธฐํ™” ํŒŒ๋ผ๋ฏธํ„ฐ
7ServletContext ์ดˆ๊ธฐํ™” ํŒŒ๋ผ๋ฏธํ„ฐ
8JNDI ์†์„ฑ, java:comp/env
9Java ์‹œ์Šคํ…œ ๋ณ€์ˆ˜, System.getProperties()
10OS ํ™˜๊ฒฝ ๋ณ€์ˆ˜
11์˜ค์ง ramdom.* ๋งŒ ์†์„ฑ์œผ๋กœ ๊ฐ–๋Š” RandomValueProertySource
12Config data
13@Confiuration ํด๋ž˜์Šค ๋‚ด @PropertySource ์–ด๋…ธํ…Œ์ด์…˜
14๊ธฐ๋ณธ properties, SpringApplication.setDefaultProperties

๐ŸŽ Command Line Properties

๊ธฐ๋ณธ์ ์œผ๋กœ SpringApplication์€ ๋ช…๋ น์ค„ ์˜ต์…˜ ์ธ์ˆ˜๋“ค์„ property๋กœ ๋ณ€ํ™˜ํ•˜๊ณ  Spring Environment์— ์ถ”๊ฐ€ํ•œ๋‹ค. Command Line Properties๋Š” ํ•ญ์ƒ ํŒŒ์ผ property ์†Œ์Šค ํŒŒ์ผ๋“ค๋ณด๋‹ค ๋” ๋†’์€ ์šฐ์„ ์ˆœ์œ„๋ฅผ ๊ฐ–๋Š”๋‹ค.

$ java -jar myproject.jar --server.port=9000

๋งŒ์•ฝ Command Line Properties๋ฅผ Environment์— ์ถ”๊ฐ€๋˜์ง€ ์•Š๊ฒŒ ํ•˜๋ ค๋ฉด, ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋น„ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค.

SpringApplication.setAddCommandLineProperties(false)

๐ŸŽ JSON Application Properties

ํ™˜๊ฒฝ ๋ณ€์ˆ˜์™€ ์‹œ์Šคํ…œ ์†์„ฑ์€ ๋ช‡๋ช‡ ์†์„ฑ๋ช…์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋Š” ์ œํ•œ์ด ์žˆ๋‹ค. ์ด๊ฒƒ์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด Spring Boot๋Š” ๋‹จ์ผ JSON ๊ตฌ์กฐ๋กœ ์†์„ฑ๋“ค์„ ์ธ์ฝ”๋”ฉํ•˜๋„๋ก ํ•ด์ค€๋‹ค.

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์‹œ์ž‘๋  ๋•Œ, spring.application.json์ด๋‚˜ SPRING_APPLICATION_JSON ์†์„ฑ๋“ค์€ ํŒŒ์‹ฑ๋˜๊ณ  Environment์— ์ถ”๊ฐ€๋œ๋‹ค.

// ํ™˜๊ฒฝ ๋ณ€์ˆ˜
$ SPRING_APPLICATION_JSON='{"my":{"name":"test"}}' java -jar myapp.jar

// ์‹œ์Šคํ…œ ์†์„ฑ
$ java -Dspring.application.json='{"my":{"name":"test"}}' -jar myapp.jar

// ๋ช…๋ น์ค„ ์ธ์ˆ˜
$ java -jar myapp.jar --spring.application.json='{"my":{"name":"test"}}'

๐ŸŽ External Application Properties

Spring Boot๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์‹œ์ž‘๋  ๋•Œ ์ž๋™์ ์œผ๋กœ ๋‹ค์Œ์˜ ์œ„์น˜์—์„œ application.properties๋‚˜ application.yaml ํŒŒ์ผ๋“ค์„ ์ฐพ๊ณ  ๋ถˆ๋Ÿฌ์˜จ๋‹ค. ๋ถˆ๋ ค์ง„ ํŒŒ์ผ๋“ค์˜ ๋‚ด์šฉ๋“ค์€ Spring Environment์— PropertySources๋กœ ์ถ”๊ฐ€๋œ๋‹ค.

์šฐ์„ ์ˆœ์œ„์œ„์น˜
1/config ํ•˜์œ„ ํด๋”์˜ ์ž์‹ ํด๋”
2ํ˜„์žฌ ํด๋”์˜ /config ํ•˜์œ„ ํด๋”
3ํ˜„์žฌ ํด๋”
4classpath /config ํŒจํ‚ค์ง€
5classpath root

๋งŒ์•ฝ "application" ์ด๋ฆ„์œผ๋กœ ์„ค์ • ํŒŒ์ผ๋ช…์„ ์‚ฌ์šฉํ•˜๊ธฐ ์‹ซ๋‹ค๋ฉด, spring.config.name ํ™˜๊ฒฝ ์†์„ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋‹ค.

$ java -jar myproject.jar --spring.config.name=myproject

spring.config.location ํ™˜๊ฒฝ ์†์„ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ช…์‹œ์  ์œ„์น˜๋ฅผ ์ฐธ์กฐํ•  ์ˆ˜ ๋„ ์žˆ๋‹ค.

$ java -jar myproject.jar --spring.config.location=\
    optional:classpath:/default.properties,\
    optional:classpath:/override.properties

Profile Specific Files

Spring Boot๋Š” application.properties ํŒŒ์ผ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ application-{profile} ๋ช…๋ช… ๊ทœ์น™์„ ์‚ฌ์šฉํ•˜์—ฌ profile-specific ํŒŒ์ผ๋“ค์„ ๋ถˆ๋Ÿฌ์˜จ๋‹ค. profile-specific properties๋Š” application.properties์™€ ๊ฐ™์€ ์œ„์น˜์—์„œ ๋ถˆ๋Ÿฌ์˜ค๋ฉฐ, application.properties๋ฅผ ํ•ญ์ƒ ์˜ค๋ฒ„๋ผ์ด๋”ฉํ•œ๋‹ค.

์•„๋ž˜์™€ ๊ฐ™์ด ํŠน์ • properties๋ฅผ ํ™œ์„ฑํ™” ํ•  ์ˆ˜ ์žˆ๋‹ค.

spring.config.activate.on-profile=prod

๐ŸŽ Properties ์•”ํ˜ธํ™”

Spring Boot๋Š” Properties ์•”ํ˜ธํ™”์— ๋Œ€ํ•œ ๋‚ด์žฅ ๊ธฐ๋Šฅ์„ ์ง€์›ํ•˜์ง€ ์•Š์ง€๋งŒ, Spring Environment ์•ˆ์— ํฌํ•จ๋œ ๊ฐ’๋“ค์„ ์ˆ˜์ •ํ•  ๋•Œ ํ•„์š”ํ•œ "hook points"๋ฅผ ์ง€์›ํ•œ๋‹ค. "EnvironmentPostProcessor" ์ธํ„ฐํŽ˜์ด์Šค๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์‹œ์ž‘ํ•˜๊ธฐ ์ „์— Environment๋ฅผ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ค€๋‹ค.

๋งŒ์•ฝ ์ž๊ฒฉ(credentials)์ด๋‚˜ ์•”ํ˜ธ๋“ค์„ ์ €์žฅํ•˜๋Š” ์•ˆ์ „ํ•œ ๋ฐฉ๋ฒ•์„ ์ฐพ๋Š”๋‹ค๋ฉด, Spring Cloud Valut ํ”„๋กœ์ ํŠธ๋Š” "HashiCorp Vault"์œผ๋กœ ์™ธ๋ถ€ํ™”๋œ ์„ค์ •์„ ์ €์žฅํ•œ๋‹ค.


๐ŸŽ Random Values

RandomValuePropertySource๋Š” ๋žœ๋คํ•œ ๊ฐ’๋“ค์„ ์ฃผ์ž…ํ•˜๊ธฐ์— ์œ ์šฉํ•˜๋‹ค. Interger, Long, UUID ํ˜น์€ String์œผ๋กœ ์ƒ์‚ฐํ•  ์ˆ˜ ์žˆ๋‹ค.

my.secret=${random.value}
my.number=${random.int}
my.bignumber=${random.long}
my.uuid=${random.uuid}
my.number-less-than-ten=${random.int(10)}
my.number-in-range=${random.int[1024,65536]}

๐ŸŽ ์‹œ์Šคํ…œ ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ๊ตฌ์„ฑ

Spring Boot๋Š” ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์œ„ํ•œ prefix ์„ค์ •์„ ์ง€์›ํ•˜๋ฉฐ SpringApplication ํด๋ž˜์Šค์— ์ง์ ‘์ ์œผ๋กœ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด ์„ค์ •์€ ์‹œ์Šคํ…œ ํ™˜๊ฒฝ์ด ๋‹ค๋ฅธ ์„ค์ • ์š”๊ตฌ์‚ฌํ•ญ์„ ๊ฐ€์ง„ ์—ฌ๋Ÿฌ Spring Boot ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๊ณต์œ ๋œ๋‹ค๋ฉด ์œ ์šฉํ•œ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, 'input'์œผ๋กœ prefix๋ฅผ ์„ค์ •ํ•˜๋ฉด, remote.timeout ๊ฐ™์€ ์†์„ฑ์€ input.remote.timeout์œผ๋กœ ์‹œ์Šคํ…œ ํ™˜๊ฒฝ์— ํ• ๋‹น๋œ๋‹ค.


๐ŸŽ Type-safe ๊ตฌ์„ฑ Properties

@Value("${property}") ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ ๊ตฌ์„ฑ ์†์„ฑ์„ ์ฃผ์ž…ํ•˜๋Š” ๊ฒƒ์€ ๋•Œ๋•Œ๋กœ ๋ฒˆ๊ฑฐ๋กœ์šธ ์ˆ˜ ์žˆ๋‹ค. ํŠนํžˆ ๋‹ค์ˆ˜์˜ ์†์„ฑ๋“ค๋กœ ์ž‘์—…ํ•˜๊ฑฐ๋‚˜ ๋ฐ์ดํ„ฐ๊ฐ€ ๊ณ„์ธต์ ์ธ ๊ฒฝ์šฐ ๋”์šฑ ๊ทธ๋Ÿฌํ•˜๋‹ค. Spring Boot๋Š” Properties๋กœ ์ž‘์—…ํ•˜๋Š” ๋Œ€์ฒด ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•˜๋ฉฐ, ๊ฐ•๋ ฅํ•˜๊ฒŒ ์ •ํ˜•ํ™”๋œ Bean์œผ๋กœ ์ œ์–ดํ•˜๊ณ  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์„ค์ •์„ ๊ฒ€์‚ฌํ•œ๋‹ค.

๐Ÿ˜ช ์™ธ๋ถ€ํ™” ์„ค์ •์€ ์ฐจํ›„ ์ถ”๊ฐ€์ ์œผ๋กœ ์ž์„ธํžˆ ์•Œ์•„๋ณด์ž.

profile
๋ฐฑ์—”๋“œ๊ฐœ๋ฐœ์ž

0๊ฐœ์˜ ๋Œ“๊ธ€