[Spring boot] ๋๋ง์ ํ๊ฒฝ ์ค์ ๋ง๋ค๊ธฐ
์ง๋ ํฌ์คํธ์์ ์๋ ํ๊ฒฝ ์ค์ ๊ณผ ๊ฐ๋ฐ, ํ๋ก๋์ , ํ ์คํธ ํ๊ฒฝ์ ๋๋๋ ๋ฐฉ๋ฒ์ ๋ํด ํฌ์คํ ํ์์ต๋๋ค. ์ด๋ฒ ํฌ์คํธ๋ ๊ทธ๊ฑฐ์ ์ด์ด์, ๋๋ง์ ํ๊ฒฝ ์ค์ ํ์ผ์ ๋ง๋๋ ๋ฐฉ๋ฒ์ ๋ํด ์์๋ณด๊ฒ ์ต๋๋ค.
@Value
์ฐ๋ฆฌ๋ ํ๊ฒฝ์ค์ ์์ Property์ ํค๋ฅผ ์ฌ์ฉํ์ฌ ํน์ ํ ๊ฐ์ ํธ์ถํ ์ ์์์ต๋๋ค. ํ์ง๋ง ์ด Key๋ก ์ฐ๋ฆฌ๊ฐ ๋ฌด์์ ํ ๊ฒ์ธ์ง๋ฅผ ํ๋ก๊ทธ๋๋ฐ ์ฝ๋์์ ๊ตฌํํด์ผ ํ๋ฉฐ, ์ผ๋จ ๊ทธ๋ฌ๊ธฐ ์ํด์๋ ์ฐ๋ฆฌ๋ ์ด ๊ฐ์ ์ด๋ป๊ฒ ๊ฐ์ ธ์ฌ ์ ์๋์ง๋ฅผ ์์์ผ ํฉ๋๋ค.
๊ทธ๋ด ๋ ์ฌ์ฉํ๋ ๊ฒ์ด @Value ์ด๋ ธํ ์ด์ ์ ๋๋ค.
# application.yml
server:
port: 8080
spring:
profiles:
active: dev
property:
app:
hello: hello world
๋จผ์ ์ฐ๋ฆฌ๋ ์๋ฒ์ ๋ฉ์ธ ๋ฉ์์ง์ ๋ํ Property๋ฅผ ๊ฐ๋จํ๊ฒ ๋ง๋ค์ด๋ณธ๋ค๊ณ ์๊ฐํ๊ณ , ์์ ๊ฐ์ด ์ฝ๋๋ฅผ YAML ์ฝ๋๋ฅผ ์ถ๊ฐํด๋ณด๊ฒ ์ต๋๋ค.
์ฌ๊ธฐ์ ์ฐ๋ฆฌ๊ฐ ๊ฐ์ ธ์์ผ ํ ๊ฐ์ 'hello world'์ด๊ณ , MainController์์ ์๋์ ๊ฐ์ด ์ฝ๋๋ฅผ ์์ฑํ๋ฉด ๋ฉ๋๋ค.
๊ทธ๋ฐ ๋ค์, ๋ฐ๋ก ์๋ฒ๋ฅผ ์คํํ๊ณ , ์ค์ ๋ ํ๊ฒฝ ํฌํธ ์ฃผ์๋ก ์ ์ํ๋ฉด....
์ด๋ ๊ฒ Property์ ๊ฐ์ ์ฝ์ด์ค๋ ๊ฒ์ ์ ์ ์์ต๋๋ค.
YAML๊ณผ @Value
์ง๋ ํฌ์คํธ์์ ์ฐ๋ฆฌ๋ Property๋ณด๋ค ๊ฐ๊ธ์ YAML์ ์ฌ์ฉํ๋ค๊ณ ๋งํ์ต๋๋ค. ๊ทธ ์ด์ ๋ YAML์ด ๋ ๋ค์ํ ๊ธฐ๋ฅ์ ์ง์ํ๊ธฐ ๋๋ฌธ์ธ๋ฐ, ์ค์ ๋ก Property๋ Key-value๋ผ๋ ๋จ์ ๊ฐ์ ํํ๋ผ๋ฉด, YAML์ ๋ฆฌ์คํธ ๋ฑ ํ Key์ ๋ณต์๊ฐ์ ๋ด์ ์ ์๋ ๋ฑ์ ํํ๋ ์ง์ํฉ๋๋ค.
๋, @Value์์๋ ๊ธฐ๋ณธ๊ฐ ์ง์ ์ต์ , ์ด๋ฅผํ ๋ฉด ๋ง์ฝ, ํ๊ฒฝ ์ค์ ํ์ผ์ ํด๋นํ๋ ๊ฐ์ด Required์ธ๋ฐ, ๋ง์ฝ ๊ฐ์ด ์๋ค๋ฉด? ๊ธฐ๋ณธ๊ฐ์ผ๋ก ๋งค๊พธ๋ ๊ฒ ํ๋ช ํ๊ฒ ์ฃ ? ์ด๋ฐ ๋ฐฉ๋ฒ๋ ์์ผ๋, ์ฐจ๊ทผ์ฐจ๊ทผ ๋ค๋ค๋ณด๋๋ก ํ์ฃ .
# application.yml
server:
port: 8080
spring:
profiles:
active: dev
property:
app:
name: Neon K.I.D Blog Example
propertyList: Java,Kotlin,Python
Property ์ฝ๋๋ฅผ ์์ ๊ฐ์ด ์์ฑํด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค. ์ด๋ฒ์๋ ๋ฆฌ์คํธ๋ ํฌํจ๋์ด ์์ฃ ?
์ด๋ฒ์๋ Tests ํด๋์ค๋ฅผ ์ด์ฉํด์ ํ ์คํธํด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค. ์ด ์ฝ๋์ ์์ฑํ ๋ค, ๋น๋๋ฅผ ํ๊ฒ ๋๋ฉด, ์ฌ๋ฌ๋ถ์ด ์ง์ ํ ์ฝ๋๋๋ก ํ ์คํธ๊ฐ ์งํ๋์๋ค๋ฉด, True ๊ทธ๋ ์ง ์์ผ๋ฉด False๋ฅผ ์ถ๋ ฅ์์ผ์ค๋๋ค.
์ฐ๋ฆฌ๋ ์ด๋ฌํ ์ฝ๋๋ฅผ ํ ์คํธ ์ฝ๋๋ผ๊ณ ์ด์ผ๊ธฐ ํฉ๋๋ค. ํ ์คํธ ์ฝ๋์ ๋ํด์๋ ๋ค๋ฅธ ํฌ์คํธ์์ ์์ธํ ํ ๋ฒ ๋ ๋ค๋ฃจ๋๋ก ํ๊ฒ ์ต๋๋ค.
๊ฐ๋จํ ์ค๋ช ์ ๋๋ฆฌ์๋ฉด, assert ํจ์๋ ํ๋ผ๋ฏธํฐ์ ์๋ ์ธ์์ ์กฐ๊ฑด์ด True์ด๋ฉด ํต๊ณผ, ๊ทธ๋ ์ง ์์ผ๋ฉด ํ ์คํธ ์คํจ๊ฐ ๋ฐ์ํ๊ฒ ๋๋ ๊ฐ๋จํ ํจ์์ ๋๋ค. ๋ฐฐ์ด ๊ฐ์ ์ฌ์ฉํ ๋๋ ArrayEquals, ๊ทธ ์ธ์ Collections์์๋ assertEquals๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ , Property Value๋ฅผ ์ค ๋๋ $๋ผ๋ ํน์ ๋ฌธ์๋ฅผ ์ฌ์ฉํ์๋๋ฐ, ์ค๊ฐ์ ๋ณด๋ฉด #์ ์ฌ์ฉํ ๊ฒ์ด ๋ณด์ผ ๊ฒ์ ๋๋ค. ์ด๋ SpEL์ด๋ผ๊ณ ํฉ๋๋ค.
What is SpEL?
SpEL์ Spring Expression Language์ ์ฝ์๋ก ์คํ๋ง ํํ ์ธ์ด๋ผ๊ณ ํฉ๋๋ค. ๋ฐํ์ ๊ฐ์ฒด ์ฐธ์กฐ์ ๋ํด ์ง์ํ๊ณ ์กฐ์ํ๋ ๊ธฐ๋ฅ์ ์ง์ํ๋ ์ธ์ด์ ๋๋ค.
์ฝ๊ฒ ๋งํ์๋ฉด, ์ฐ๋ฆฌ๊ฐ ์์์ ์งฐ๋ YAML ์ฝ๋์ฒ๋ผ ๋ฆฌ์คํธ๋ String์ด ์ฃผ์ด์ง๊ฒ ๋๋ฉด, ํด๋น ๊ฐ์ฒด๋ฅผ ๋ฐํ์์ ์ฐธ์กฐํ๊ฒ ๋๋๋ฐ, ๊ทธ ๋ ์ฌ์ฉํ๋ ๋ฉ์๋ ๋ฑ์ ํธ์ถํ๊ณ , ๊ธฐ๋ณธ ๋ฌธ์์ด ํ ํ๋ฆฟ ๊ธฐ๋ฅ์ ์ง์ํจ์ผ๋ก์จ, ๋ค์ํ ์ปฌ๋ ์ ์๊ณ ๋ฆฌ์ฆ์ ํตํด ํ๋ก๊ทธ๋๋ฐ ๊ตฌํ์ ๋ค์์ฑ์ ํฌํจ์ํจ ๊ฒ์ด์ฃ .
์ด๋ @Value ์ด๋ ธํ ์ด์ ์์๋ง ์ฌ์ฉํ ์ ์์ต๋๋ค.
์ฑ๊ณต์ ์ผ๋ก ๋ชจ๋ ๊ฒฐ๊ณผ๊ฐ ์ ํํ๊ฒ ์ถ๋ ฅ๋์๋ค๋ฉด, exit code 0์ ๋ฐํํฉ๋๋ค. ๋ง์ฝ ์คํจํ๋ค๋ฉด, exit code๊ฐ 0์ด ์๋ ๋ค๋ฅธ ๊ฐ์ผ๋ก ํ์๋๋ฉฐ, ๋นจ๊ฐ ํ๋ฉด์ด ํ์๋ ๊ฒ์ ๋๋ค.
์ฌ๊ธฐ์ ์ฃผ์ํ ์ ์ YAML ํ์ผ์์ Array๋ List๋ฅผ ์ด์ฉํ ๊ฒฝ์ฐ, ๊ฐ ์์๋ค์ ๊ณต๋ฐฑ์ ์ฃผ์ง๋ง์ธ์. ๊ณต๋ฐฑ์ ์ฃผ๊ฒ ๋ ๊ฒฝ์ฐ, Java ์ฝ๋์์๋ ๊ทธ๋๋ก ๋ณ์ ๊ฐ์ ๋ฐ์๋์ด, ํ ์คํธ ์ค์ ๋ฌธ์ ๊ฐ ์์ ์ ์์ต๋๋ค.
์ฌ๊ธฐ๊น์ง ๊ฐ๋จํ๊ฒ @Value ์ด๋ ธํ ์ด์ ๊ณผ ํจ๊ป SpEL์ ์ฌ์ฉํด๋ดค์ต๋๋ค. ๊ฐ๋จํ ์์ฝํ์๋ฉด, YAML ํ์ผ์์ ์ค์ ํ ํค๊ฐ์ @Value์ ํ๋กํผํฐ ๊ฐ์ผ๋ก ์ฃผ๊ฒ ๋๋ฉด ํด๋น ๊ฐ์ด ํ๋๊ฐ์ ํ ๋น๋๋ ๋ฐฉ์์ผ๋ก ์ด์์๊ฐ ํ ๊ฐ์ ์ค์ ํ์ผ์ ๊ฑด๋๋ ค์ ๋๋ง์ ์๋ฒ ์ปค์คํ ํ๊ฒฝ ์ค์ ์ ๊ตฌํํ ์ ์๋ ๊ฒ์ด ํคํฌ์ธํธ์ ๋๋ค. ์ฆ, ๊ฐ๋ฅํ ํ๋ก๊ทธ๋๋ฐ ์ฝ๋๋ฅผ ๊ฑด๋๋ฆฌ์ง ์๊ณ , ์๋ฒ๋ฅผ ์ค์ ํ ์ ์๋๋ก ํ๋ ๋ชฉ์ ์ ์ง๋๊ณ ์์ฃ .
@ConfigurationProperties
์ข ๋ ๊ณ ๊ธ์ ์ธ ์ฌ์ฉ๋ฒ์ผ๋ก๋ ConfigurationProperties ์ด๋ ธํ ์ด์ ์ ๋ณผ ์ ์์ต๋๋ค. ์ด ์ด๋ ธํ ์ด์ ์ ๋ค์ํ ์๋ฃํ์ Property ๊ฐ์ ๋งคํํ ์ ์๋๋ก ํด์ฃผ๋ ๋ ์์ธ๋ฐ, ์ด ๋ ์์ ์ฌ์ฉํ๋ ค๋ฉด ๋ช ๊ฐ์ง ์ ์ฝ์ ๋ฐ๋ผ์ผ ํฉ๋๋ค.
- ConfigurationProperties๋ Root Prefix๋ฅผ ํ์ฉํ์ฌ ์ํ๋ ๊ฐ์ฒด์ ๋ฐ์ธ๋ฉ (Root Prefix ํ์)
- List, Map๊ณผ ๊ฐ์ ๋ค์์ ์๋ฃ๋ฅผ ๋ด๋ ์ฌ์ฉ์ ์ ์ Property์ด๊ธฐ ๋๋ฌธ์ ํด๋์ค๋ฅผ ๋ณ๋๋ก ์์ฑํด์ผ ํจ.
- ํด๋น Property ์ฌ์ฉ์ ์ํด DI(์์กด์ฑ ์ฃผ์ )์ ํ์, ๋ฐ๋ผ์ @Component or @ConstructorBinding ์ด๋ ธํ ์ด์ ์ ์ ์ธํด์ผ ํจ.
- ConfigurationProperties๋ฅผ ํ์ฉํด ํด๋์ค์ List or Map ํ๋๋ก ๋ฐ์ธ๋ฉ ๋๋ฏ๋ก, data class ๋ฑ์ ์ด์ฉํ์ฌ์ผ ํจ.
- Application ํด๋์ค์์ @EnableConfigurationProperties ์ด๋ ธํ ์ด์ ์ผ๋ก Property ํด๋์ค๋ฅผ ์ ์ธํด์ผ ํจ.
์ ์ฝ ์ฌํญ์ด ์กฐ๊ธ ๋ง์ ํธ์ด์ง๋ง, ๋๋ถ๋ถ์ Spring์์ ํ ํด๋์ค๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด ๊ธฐ๋ณธ์ ์ผ๋ก ํด์ผํ๋ ์ผ์ ๋ช ์ํ ๊ฒ์ด ๋๋ถ๋ถ์ ๋๋ค. ํนํ, ๋ง์ง๋ง ์ ์ฝ ์ฌํญ์ ๊ฒฝ์ฐ, Java์์๋ Lombok์ด๋ผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํด์๋ ์ฝ๊ฒ ๊ตฌํํ ์ ์๊ณ , Kotlin์์๋ ์ธ์ด์์ ์์ฒด์ ์ผ๋ก data class๋ฅผ ์ง์ํด์ฃผ๊ธฐ ๋๋ฌธ์ ์ด๋ ต์ง ์๊ฒ ๊ตฌํํ ์ ์์ต๋๋ค.
4๋ฒ ์ ์ฝ ์ฌํญ์ ๊ฒฝ์ฐ๋ ์ต๊ทผ์ ๊ฐ์ ๋ ์ฌํญ์ธ๋ฐ, ๊ธฐ์กด Property๋ Mutableํ ๊ฐ์ด์ด์, ์ค๊ฐ์ ํ๋ก๊ทธ๋๋ฐ์ ์ํด ๋ฐ๋ ์๋ ์์ด, ์ํ์ฑ์ด ์ปธ๋๋ฐ, ํนํ Java ์ธ์ด์์ ์ฌ์ฉ๋๋ Lombok ์ด๋ setter๋ฅผ ์ด์ฉํ ๋ฐ์ธ๋ฉ์ ๊ฐ๋ณ์ฑ ํน์ง์ ๊ฐ์ง๊ณ ์์ด, ๋ฐ์ดํฐ ๋ณ์กฐ์ ์ํ์ด ์์์ฃ .
ํ์ง๋ง Kotlin์์๋ ์ ๊ทผ ์ง์ ์ ๋ฑ์ผ๋ก ๊ฐ๋ณ์ฑ, ๋ถ๋ณ์ฑ์ ์ ์ดํ ์ ์๊ธฐ ๋๋ฌธ์ ์ด๋ฌํ ๋ถํธํจ์ ์ค์ผ ์ ์์ง๋ง, ๊ธฐ์กด Spring/Spring boot์์๋ ๊ฐ๋ณ์ฑ๋ง ์ ๊ณตํ์์์ฃ . ๊ทธ๊ฑธ ๊ฐ์ ํ ๊ฒ์ด @ConstructorBinding ์ ๋๋ค. ๋ฐ๋ผ์ ์ด ์ด๋ ธํ ์ด์ ์ ์ด์ฉํ๋ฉด, ๋ถ๋ณ์ฑ์ธ Property๋ฅผ ์์ฑํ ์ ์์ต๋๋ค.
5๋ฒ ์ ์ฝ ์ฌํญ์ ๊ฒฝ์ฐ, ๊ณผ๊ฑฐ์๋ @ConfigurationPropertiesScan ์ด๋ผ๋ ์ด๋ ธํ ์ด์ ์ ์ด์ฉํ์ฌ Property๋ฅผ ์๋์ผ๋ก Scan ํด์ฃผ๋ ๊ธฐ๋ฅ์ ๊ฐ์ง๊ณ ์์์ง๋ง Spring boot 2.2.1 ๋ฒ์ ๋ถํฐ๋ ์ผ๋ถ ์ ๊ท ์ด๋ ธํ ์ด์ ๊ณผ์ ๋ฌธ์ ๋ก ์ธํ์ฌ disabled ๋์ด ์ง๊ธ์ ์๋์ผ๋ก Property ํด๋์ค๋ฅผ ๋ช ์ํด ์ค์ผ ํฉ๋๋ค.
๊ทธ๋ผ ๊ตฌํ์ ํ ๋ฒ ํด๋ณด๋๋ก ํ์ฃ .
# application.yml
server:
port: 8080
spring:
profiles:
active: dev
language:
list:
- name: C++
type: Object-Oriented
- name: F#
type: Functional
- name: PowerShell
type: script
๊ธฐ์กด์ property๋ฅผ ์ง์ฐ๊ณ , ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์ ๊ฐ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์ ํ์ ์ ๋ํ๋ด๋ ๋งต ๋ฆฌ์คํธ๋ฅผ ํ ๊ฐ ๋ง๋ค์ด๋ดค์ต๋๋ค.
LangProperty ๋ผ๋ ์ด๋ฆ์ผ๋ก ์ฌ๋ฌ๋ถ๋ค์ ์ ์ํ Property์ ํด๋์ค๋ฅผ ๋ง๋ค์ด์ฃผ๋๋ก ํฉ๋๋ค.
data class๋ฅผ ์ด์ฉํ์ฌ ์์ ๊ฐ์ด ๋ถ๋ณ์ฑ Property๋ฅผ ๋ฐ์ธ๋ฉํ ํด๋์ค๋ฅผ ์์ฑํด์ฃผ์๋ฉด ๋ฉ๋๋ค. ๋ง์ง๋ง์ผ๋ก ์ด๋ค Property์ธ์ง Prefix๋ฅผ ๋ช ์ํด์ค์๋ค.
๊ทธ๋ฆฌ๊ณ Application ํด๋์ค์ Property์ ์ฌ์ฉ์ ์ ์ธํด์ค๋๋ค.
ํ ์คํธ ์ฝ๋๋ ์์ ๊ฐ์ด ์์ฑํด๋ณด๋๋ก ํ๊ณ , ์ ํ๋ฆฌ์ผ์ด์ ์ ์คํํ๋ฉด...
์ด๋ ๊ฒ ์ฑ๊ณตํ๋ ๋ชจ์ต์ ๋ณผ ์ ์์ต๋๋ค. ๊ทธ๋ฐ๋ฐ, ํ ์คํธ ์ฝ๋๊ฐ ์ฉ ๋ณด๊ธฐ ์ข์ง ์์ฃ . ์ ํ๋ฆฌ์ผ์ด์ ๋ด์์๋ Map์ ์ฌ์ฉํจ์ผ๋ก์จ ๋ฐ์ดํฐ๋ฅผ ์ฃผ๋ฌด๋ฅด๋ ๊ฒ ํธํ์ง๋ง, ์ถ๋ ฅํ ๋๋ ๊ทธ๋ ๊ฒ ์ข์ ๋ชจ์ต์ ์๋ ๊ฒ ๊ฐ๋ค์.
์ด๋ด ๋๋ POJO ํ์ ์ด ์ข์ต๋๋ค. POJO ํ์ ์ List<Map>๋ณด๋ค ๋ ์ง๊ด์ ์ด๊ณ , ๋ ๋ช ํํ๊ฒ ๊ฐ์ฒด๋ฅผ ๊ตฌ์ฑํ ์ ์์ด, ์ฐ๋ฆฌ๊ฐ ์ค์ ๋ก Spring boot์์ REST API๋ฅผ ๊ตฌํํ ๋ ๋ง์ด ์ฌ์ฉํ๊ฒ ๋ ๊ฒ์ ๋๋ค.
POJO
POJO๋ Plain Old Java Object์ ์ฝ์์ ๋๋ค. ์ Old๊ฐ ๋ถ์ด ์์ผ๋ฉด ์ข ์ค๋๋๊ณ ์์จ์ผ ๋๋ ๊ฒ ๋ง์ง ์์๊น์? ๋ผ๋ ๋ถ๋ค๋ ๊ณ์ค ์ ์์ ๊ฒ์ ๋๋ค.
ํ์ง๋ง POJO๋ ํน์ ํ๊ฒฝ์ ์ข ์๋์ง๋ ์๊ณ , ํนํ ๋จ์ผ ์ฑ ์์ ์์น์ด๋ผ๋ ๊ฒ์ด ์ ๋์ด ์์ด, ๊ฐ์ฒด ์งํฅ์ ์ด๊ณ ์ข์ต๋๋ค. ๋จ์ผ ์ฑ ์์ ์์น์ด๋ ๊ฒ์ ํ ํด๋์ค์์ ๊ฐ๊ธฐ ์ฑ ์๊ณผ ์ญํ ์ด ๋ช ํํ๊ฒ ์ ํด์ ธ ์๋ ์์น์ด์ฃ . ์ค์ ๋ก ์ ๋ ์ด ์์น ๋๋ฌธ์ OOP๋ฅผ ์ ํธํ๋ ํธ์ด๊ธฐ๋ ํฉ๋๋ค.
DB๋ ์ฐ๋ํ ๋๋ ๋ง์ ์ฅ์ ์ ๊ฐ์ง๊ณ ์๋ ์ฐฉํ ๋ ์์ด๋, ์กฐ๊ธ์ฉ ๋ค๋ค๋ณด์๋ฉด์ ์ตํ ๋๊ฐ์๋ฉด ๊ทธ ์ฅ์ ์ด ๋์ฑ ์ ๋ณด์ผ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
์ ๊ทธ๋ผ POJO ํํ๋ก ํ ๋ฒ ๋ง๋ค์ด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
์ค์ ๋ก ์๊ณ ๋ฆฌ์ฆ์ ์งค ๋๋, Map์ ์ฐ๊ธฐ ์ซ์ผ๋ฉด ์ ๋ ๋ณดํต ์ด๋ ๊ฒ ํ๋ ๊ฒฝ์ฐ๊ฐ ์๋๋ฐ, data class๋ฅผ ์ฌ์ฉํ๊ฒ ๋๋ฉด, ์ด๋ ๊ฒ ์ฌํํ๊ฒ ๋ง๋ค ์ ์์ต๋๋ค.
์ด์ Map ๋์ , POJO ํ์ ์ ๋ฆฌ์คํธ๋ก ๋ฃ์ด์ฃผ๋ฉด ๋๊ฒ ์ฃ ?
์ด ๋ค์ ๊ณผ์ ๋ ์์ ํ ์คํธ ์ฝ๋๋ฅผ ์ฌ๋ฌ๋ถ๋ค์ด ์ง๋ณด๋ ๊ฒ์ ๋๋ค. Map ๋์ ํด๋์ค๋ฅผ ์ด์ฉํ ๊ฒ์ด๋, ์ฝ๊ฒ ์ง๋ณด์ค ์ ์์ ๊ฒ์ ๋๋ค.