Beans(๋นˆ)

์Šคํ”„๋ง ๋นˆ(Bean) : ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์ƒ์„ฑํ•˜๊ณ  ์ƒ๋ช…์ฃผ๊ธฐ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ์ž๋ฐ” ๊ฐ์ฒด

Bean์€ ์Šคํ”„๋ง์„ ๊ตฌ์„ฑํ•˜๋Š” ํ•ต์‹ฌ ์š”์†Œ๋กœ, ๋นˆ ์ •์˜ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ(BeanDefinition)๋กœ ๋“ฑ๋ก๋˜๊ณ  ์ปจํ…Œ์ด๋„ˆ๋Š” ํ•ด๋‹น ์ •์˜์— ๋”ฐ๋ผ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑ, ์˜์กด์„ฑ ์ฃผ์ž…, ์ดˆ๊ธฐํ™”, ์†Œ๋ฉธ๊นŒ์ง€ ๊ด€๋ฆฌํ•œ๋‹ค.

ํ•ต์‹ฌ ๊ตฌ์„ฑ ์š”์†Œ

  1. class

    • ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•  Java ํด๋ž˜์Šค

    • ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์— ์˜ํ•ด ๊ฐ์ฒด๋กœ ์ƒ์„ฑ ๋ฐ ๊ด€๋ฆฌ๋˜์–ด ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ Bean์œผ๋กœ ์‚ฌ์šฉ

  2. id

    • ์ปจํ…Œ์ด๋„ˆ์—์„œ ๋นˆ์„ ์‹๋ณ„ํ•˜๊ธฐ ์œ„ํ•œ ๊ณ ์œ  ์‹๋ณ„์ž

    • ํด๋ž˜์Šค๋ช…์„ decapitalizeํ•œ ์ด๋ฆ„์„ ๊ธฐ๋ณธ์œผ๋กœ ๋ถ€์—ฌํ•˜๋ฉฐ, ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ • ๊ฐ€๋Šฅ

  3. scope

    • ๋นˆ ์ธ์Šคํ„ด์Šค์˜ ์ƒ์กด ๋ฒ”์œ„ ์ •์˜

    • ๊ธฐ๋ณธ๊ฐ’ singleton

  4. constructor-arguments

    • Bean์„ ์ƒ์„ฑํ•  ๋•Œ ์ƒ์„ฑ์ž์— ์ „๋‹ฌํ•  ์ธ์ž๋“ค์„ ์ •์˜

    • Bean์„ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ

  5. property

    • Bean์„ ์ƒ์„ฑํ•  ๋•Œ setter๋ฅผ ํ†ตํ•ด ์ „๋‹ฌํ•  ์ธ์ž๋“ค์„ ์ •์˜

  6. ๊ธฐํƒ€ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ

    • initMethod, destroyMethod, lazyInit, primary, autowireCandidate, dependsOn, description ๋“ฑ

์Šคํ”„๋ง ๋นˆ ๋“ฑ๋ก ๋ฐฉ๋ฒ•

1. ์ปดํฌ๋„ŒํŠธ ์Šค์บ”

์ปดํฌ๋„ŒํŠธ ์Šค์บ”์œผ๋กœ ์–ด๋…ธํ…Œ์ด์…˜์ด ๋ถ€์—ฌ๋œ ํด๋ž˜์Šค๋ฅผ ์ž๋™ ํƒ์ง€ํ•˜์—ฌ ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•œ๋‹ค.

  • ์‚ฌ์šฉ ์–ด๋…ธํ…Œ์ด์…˜: @Component ์™€ ํŠนํ™” ์–ด๋…ธํ…Œ์ด์…˜(@Controller, @Service, @Repository, ๋“ฑ)

  • ํƒ์ƒ‰ ๋ฒ”์œ„: @ComponentScan ์˜ basePackages, basePackageClasses, includeFilters, excludeFilters๋กœ ์ œ์–ด

  • ์ด๋ฆ„ ๊ทœ์น™: ๊ธฐ๋ณธ์€ ํด๋ž˜์Šค๋ช… decapitalize. @Component("customName")๋กœ ์ง€์ • ๊ฐ€๋Šฅ

์˜์กด์„ฑ ์ฃผ์ž…์€ ๋ฐฉ๋ฒ•์œผ๋ก  ์—ฌ๋Ÿฌ ๊ฐ€์ง€๊ฐ€ ์žˆ๋Š”๋ฐ, ๊ทธ ์ค‘ ์ƒ์„ฑ์ž ์ฃผ์ž… ๋ฐฉ๋ฒ•์„ ๊ถŒ์žฅํ•˜๊ณ  ์žˆ๋‹ค.(๋‹จ์ผ ์ƒ์„ฑ์ž์ผ ๊ฒฝ์šฐ @Autowired ์ƒ๋žต ๊ฐ€๋Šฅ)

2. ์ž๋ฐ” ์„ค์ •(@Configuration + @Bean)

์ •ํ˜•ํ™” ๋˜์ง€ ์•Š์€ ์ฝ”๋“œ๊ฑฐ๋‚˜, ์ƒํ™ฉ์— ๋”ฐ๋ผ ๊ตฌํ˜„ ํด๋ž˜์Šค๋ฅผ ๋ณ€๊ฒฝํ•ด์•ผํ•˜๋Š” ๊ฒฝ์šฐ ์‚ฌ์šฉํ•œ๋‹ค.

@Configuration์— ๋‘ ๊ฐ€์ง€ ์†์„ฑ์ด ์กด์žฌํ•˜๋Š”๋ฐ, ๊ฐ ์—ญํ• ์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  • value: @Configuration ์„ ์–ธ๋œ ํด๋ž˜์Šค์˜ ์ด๋ฆ„์„ ์ง€์ •

  • proxyBeanMethods: ์Šคํ”„๋ง์ด ๊ด€๋ฆฌํ•˜๋Š” ๋นˆ์„ ์ฐธ์กฐํ•  ๋•Œ ํ”„๋ก์‹œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‹ฑ๊ธ€ํ†ค ๋ณด์žฅ(๊ธฐ๋ณธ๊ฐ’ true)

    • ์ง์ ‘ ์ƒ์„ฑํ•œ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ, CGLIB์— ์˜ํ•ด ์ƒ์„ฑ๋œ ํ”„๋ก์‹œ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‹ฑ๊ธ€ํ†ค ๋ณด์žฅ

๋นˆ ์ƒ๋ช…์ฃผ๊ธฐ

์Šคํ”„๋ง ๋นˆ์€ ์ƒ์„ฑ - ์˜์กด๊ด€๊ณ„ ์ฃผ์ž… ๋‹จ๊ณ„๋ฅผ ๊ฑฐ์ณ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ƒํƒœ๊ฐ€ ๋˜๋ฉฐ, ์Šคํ”„๋ง ๋นˆ์˜ ๋Œ€๋žต์ ์ธ ์ด๋ฒคํŠธ ๋ผ์ดํ”„ ์‚ฌ์ดํด์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

  1. ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ ์ƒ์„ฑ

  2. ์Šคํ”„๋ง ๋นˆ ์ƒ์„ฑ ๋ฐ ๋“ฑ๋ก

    • Bean์œผ๋กœ ๋“ฑ๋กํ•  ์ˆ˜ ์žˆ๋Š” Annotation ๋ฐ Configuration์„ ์ฝ์–ด IoC ์ปจํ…Œ์ด๋„ˆ ์•ˆ์— Bean์œผ๋กœ ๋“ฑ๋ก

    • ์˜์กด ๊ด€๊ณ„ ์ฃผ์ž… ์ „ ๊ฐ์ฒด ์ƒ์„ฑ ๊ณผ์ • ์ˆ˜ํ–‰(Field/Setter ์ฃผ์ž…์˜ ๊ฒฝ์šฐ์—๋งŒ)

      • ์ƒ์„ฑ์ž ์ฃผ์ž…: ๊ฐ์ฒด์˜ ์ƒ์„ฑ๊ณผ ์˜์กด๊ด€๊ณ„ ์ฃผ์ž…์ด ๋™์‹œ์— ๋ฐœ์ƒ

      • Setter/Field ์ฃผ์ž…: ๊ฐ์ฒด ์ƒ์„ฑ -> ์˜์กด ๊ด€๊ณ„ ์ฃผ์ž… ๋‹จ๊ณ„ ๋ถ„๋ฆฌ

  3. ์ดˆ๊ธฐํ™” ์ฝœ๋ฐฑ

    • ๋นˆ์ด ์ƒ์„ฑ๋˜๊ณ , ๋นˆ์˜ ์˜์กด๊ด€๊ณ„ ์ฃผ์ž…์ด ์™„๋ฃŒ๋œ ํ›„ ํ˜ธ์ถœ

  4. ๋Ÿฐํƒ€์ž„ ์‚ฌ์šฉ

    • ์‹ค์ œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜(๋นˆ) ๋™์ž‘ ๋‹จ๊ณ„

  5. ์†Œ๋ฉธ ์ „ ์ฝœ๋ฐฑ

    • ๋นˆ์ด ์†Œ๋ฉธ๋˜๊ธฐ ์ง์ „์— ํ˜ธ์ถœ

  6. ์Šคํ”„๋ง ์ข…๋ฃŒ

๋นˆ ์ƒ๋ช…์ฃผ๊ธฐ(์ดˆ๊ธฐํ™”/์†Œ๋ฉธ) ์ฝœ๋ฐฑ

๋นˆ์€ ์‹œ์ž‘ ๋ฐ ์ข…๋ฃŒ ์‹œ์ ์— ์ถ”๊ฐ€์ ์ธ ์ฝœ๋ฐฑ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์•„๋ž˜ ์„ธ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•œ๋‹ค.(์‹คํ–‰๋˜๋Š” ์ˆœ์„œ๋Š” ์•„๋ž˜ ๋ฒˆํ˜ธ ์ˆœ์„œ๋Œ€๋กœ ์‹คํ–‰)

1. @PostConstruct, @PreDestroy ์• ๋…ธํ…Œ์ด์…˜

  • @PostConstruct: ์˜์กด๊ด€๊ณ„ ์ฃผ์ž…์ด ๋๋‚˜๋ฉด ํ˜ธ์ถœ

  • @PreDestroy: ๋นˆ์ด ์ข…๋ฃŒ๋  ๋•Œ ํ˜ธ์ถœ

  • ์ตœ์‹  ์Šคํ”„๋ง์—์„œ ๊ฐ€์žฅ ๊ถŒ์žฅํ•˜๋Š” ๋ฐฉ๋ฒ•

  • javax.annotation.PostConstruct์ธ ์ž๋ฐ” ํ‘œ์ค€ ๊ธฐ์ˆ 

  • ์ปดํฌ๋„ŒํŠธ ์Šค์บ”๊ณผ ๊ถํ•ฉ์ด ์ข‹์Œ

  • ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—๋Š” ์ ์šฉ ๋ถˆ๊ฐ€๋Šฅ -> ์ด ๊ฒฝ์šฐ @Bean์˜ initMethod, destroyMethod๋ฅผ ์‚ฌ์šฉ

2. ์ธํ„ฐํŽ˜์ด์Šค(InitializingBean, DisposableBean)

  • InitializingBean In afterPropertiesSet(): ์˜์กด๊ด€๊ณ„ ์ฃผ์ž…์ด ๋๋‚˜๋ฉด ํ˜ธ์ถœ

  • DisposableBean In destroy(): ๋นˆ์ด ์ข…๋ฃŒ๋  ๋•Œ ํ˜ธ์ถœ

  • ์Šคํ”„๋ง ์ „์šฉ ์ธํ„ฐํŽ˜์ด์Šค์— ์˜์กด

  • ์ดˆ๊ธฐํ™”, ์†Œ๋ฉธ ๋ฉ”์„œ๋“œ์˜ ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋ถˆ๊ฐ€

  • ์ฝ”๋“œ๋ฅผ ๊ณ ์น  ์ˆ˜ ์—†๋Š” ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ์ ์šฉ ๋ถˆ๊ฐ€

3. ์„ค์ • ์ •๋ณด์— ์ดˆ๊ธฐํ™” ๋ฉ”์„œ๋“œ, ์ข…๋ฃŒ ๋ฉ”์„œ๋“œ ์ง€์ •

  • @Bean(initMethod = "init", destroyMethod = "close") ์ดˆ๊ธฐํ™”/์†Œ๋ฉธ ๋ฉ”์„œ๋“œ ์ง€์ •

  • ๋ฉ”์„œ๋“œ ์ด๋ฆ„ ์ž์œ ๋กญ๊ฒŒ ์„ค์ • ๊ฐ€๋Šฅ

  • ์Šคํ”„๋ง ๋นˆ์ด ์Šคํ”„๋ง ์ฝ”๋“œ์— ์˜์กดํ•˜์ง€ ์•Š์Œ

  • ์„ค์ • ์ •๋ณด๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ฝ”๋“œ๋ฅผ ๊ณ ์น  ์ˆ˜ ์—†๋Š” ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—๋„ ์ดˆ๊ธฐํ™”, ์ข…๋ฃŒ ๋ฉ”์„œ๋“œ ์ ์šฉ ๊ฐ€๋Šฅ

  • ์ข…๋ฃŒ ๋ฉ”์„œ๋“œ ์ถ”๋ก  ๊ธฐ๋Šฅ

    • @Bean์˜ destroyMethod ์†์„ฑ์—๋Š” ์•„๋ฌด๊ฒƒ๋„ ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ์ถ”๋ก  ๊ธฐ๋Šฅ์ด ๋™์ž‘

    • close, shutdown ๊ฐ™์€ ์ผ๋ฐ˜์ ์œผ๋กœ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” ์ข…๋ฃŒ ๋ฉ”์„œ๋“œ๋ฅผ ์ž๋™์œผ๋กœ ํ˜ธ์ถœ

    • ์ถ”๋ก  ๊ธฐ๋Šฅ์„ ๋ง‰๊ธฐ ์œ„ํ•ด์„œ destroyMethod=""๋กœ ์ง€์ • ํ•  ์ˆ˜ ์žˆ์Œ

์Šค์ฝ”ํ”„

๋นˆ์ด ์กด์žฌํ•  ์ˆ˜ ์žˆ๋Š” ๋ฒ”์œ„๋ฅผ ๋œปํ•˜๋ฉฐ, ์Šคํ”„๋ง ๋นˆ์ด ๊ธฐ๋ณธ์ ์œผ๋กœ ์‹ฑ๊ธ€ํ†ค ์Šค์ฝ”ํ”„๋กœ ์ƒ์„ฑ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋ณดํ†ต ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์˜ ์‹œ์ž‘๊ณผ ์ข…๋ฃŒ ์‹œ์ ๊ณผ ๊ฐ™์œผ๋ฉฐ ํฌ๊ฒŒ ์„ธ ๊ฐ€์ง€ ์Šค์ฝ”ํ”„๋ฅผ ์ง€์›ํ•œ๋‹ค.

  • ์‹ฑ๊ธ€ํ†ค(Default): ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์˜ ์‹œ์ž‘๊ณผ ์ข…๋ฃŒ ์‹œ์ ์— ์ƒ์„ฑ๋˜๊ณ  ์†Œ๋ฉธํ•˜๋Š” ๊ฐ€์žฅ ๋„“์€ ๋ฒ”์œ„์˜ ์Šค์ฝ”ํ”„, ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉ๋˜๋Š” ์Šค์ฝ”ํ”„

  • ํ”„๋กœํ† ํƒ€์ž…: ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ๋นˆ์˜ ์ƒ์„ฑ๊ณผ ์˜์กด ๊ด€๊ณ„ ์ฃผ์ž…๊นŒ์ง€๋งŒ ๊ด€์—ฌํ•˜๊ณ  ๋”๋Š” ๊ด€๋ฆฌํ•˜์ง€ ์•Š๋Š” ์Šค์ฝ”ํ”„

  • ์›น ๊ด€๋ จ ์Šค์ฝ”ํ”„

    • request: ์›น ์š”์ฒญ ํ•˜๋‚˜๊ฐ€ ๋“ค์–ด์˜ค๊ณ  ๋‚˜๊ฐˆ ๋•Œ ๊นŒ์ง€ ์œ ์ง€๋˜๋Š” ์Šค์ฝ”ํ”„

    • session: ์›น Session๊ณผ ๋™์ผํ•œ ์ƒ๋ช…์ฃผ๊ธฐ๋ฅผ ๊ฐ€์ง€๋Š” ์Šค์ฝ”ํ”„

    • application: ์„œ๋ธ”๋ฆฟ ์ปจํ…์ŠคํŠธ์™€ ๋™์ผํ•œ ์ƒ๋ช…์ฃผ๊ธฐ๋ฅผ ๊ฐ€์ง€๋Š” ์Šค์ฝ”ํ”„

ํ”„๋กœํ† ํƒ€์ž… ์Šค์ฝ”ํ”„

์‹ฑ๊ธ€ํ†ค ์Šค์ฝ”ํ”„๋Š” ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์—์„œ ํ•ญ์ƒ ๊ฐ™์€ ์ธ์Šคํ„ด์Šค์˜ ์Šคํ”„๋ง ๋นˆ์„ ๋ฐ˜ํ™˜ํ•˜์ง€๋งŒ, ์Šค์ฝ”ํ”„์˜ ๋นˆ์€ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์— ์š”์ฒญํ•  ๋•Œ๋งˆ๋‹ค ์ƒˆ๋กœ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

  • ์‹ฑ๊ธ€ํ†ค ๋นˆ / ํ”„๋กœํ† ํƒ€์ž… ๋นˆ ๋น„๊ต

์‹ฑ๊ธ€ํ†ค ๋นˆ
ํ”„๋กœํ† ํƒ€์ž… ๋นˆ

์‹ฑ๊ธ€ํ†ค ์Šค์ฝ”ํ”„ ๋นˆ์„ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์— ์š”์ฒญ

ํ”„๋กœํ† ํƒ€์ž… ์Šค์ฝ”ํ”„ ๋นˆ์„ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์— ์š”์ฒญ

(์š”์ฒญ ํ•œ ๋นˆ์ด ์ด๋ฏธ ์ƒ์„ฑ๋˜์–ด ์žˆ๋Š” ์ƒํƒœ)

์š”์ฒญ ์˜จ ์‹œ์ ์— ํ”„๋กœํ† ํƒ€์ž… ๋นˆ์„ ์ƒ์„ฑํ•˜๊ณ  ์˜์กด ๊ด€๊ณ„ ์ฃผ์ž…

์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ๊ด€๋ฆฌํ•˜๊ณ  ์žˆ๋Š” ๋นˆ ๋ฐ˜ํ™˜

์ƒ์„ฑํ•œ ๋นˆ์„ ๋ฐ˜ํ™˜

๊ฐ™์€ ์š”์ฒญ์ด ์™€๋„ ๊ณ„์† ๊ฐ™์€ ์ธ์Šคํ„ด์Šค์˜ ์Šคํ”„๋ง ๋นˆ ๋ฐ˜ํ™˜

๊ฐ™์€ ์š”์ฒญ์ด ์˜ค๋ฉด ๊ณ„์† ์ƒˆ๋กœ์šด ์ธ์Šคํ„ด์Šค์˜ ์Šคํ”„๋ง ๋นˆ ๋ฐ˜ํ™˜

ํ”„๋กœํ† ํƒ€์ž… ๋นˆ์˜ ํŠน์ง•์„ ์ •๋ฆฌํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  • ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์— ์š”์ฒญํ•  ๋•Œ ๋งˆ๋‹ค ์ƒˆ๋กœ์šด ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑ

  • ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋Š” ํ”„๋กœํ† ํƒ€์ž… ์Šค์ฝ”ํ”„ ๋นˆ์„ ์ƒ์„ฑ/์˜์กด๊ด€๊ณ„ ์ฃผ์ž…/์ดˆ๊ธฐํ™”๊นŒ์ง€๋งŒ ์ฒ˜๋ฆฌ

  • ์ƒ์„ฑ ๋ฐ ์ดˆ๊ธฐํ™”๊นŒ์ง€๋งŒ ์ฒ˜๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— @PreDestroy ๊ฐ™์€ ์ข…๋ฃŒ ๋ฉ”์„œ๋“œ๋„ ํ˜ธ์ถœํ•˜์ง€ ์•Š์Œ

  • ํ”„๋กœํ† ํƒ€์ž… ๋นˆ์€ ํ”„๋กœํ† ํƒ€์ž… ๋นˆ์„ ์กฐํšŒํ•œ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๊ด€๋ฆฌ

  • ์—ฌ๋Ÿฌ ๋นˆ์—์„œ ๊ฐ™์€ ํ”„๋กœํ† ํƒ€์ž… ๋นˆ์„ ์ฃผ์ž… ๋ฐ›์œผ๋ฉด, ์ฃผ์ž… ๋ฐ›์€ ๋ชจ๋“  ๋นˆ์€ ๊ฐ์ž ๋‹ค๋ฅธ ์ธ์Šคํ„ด์Šค๋ฅผ ์‚ฌ์šฉ(ํ•˜๋‚˜์˜ ๋นˆ์—์„  ๊ณ„์† ๊ฐ™์€ ํ”„๋กœํ† ํƒ€์ž… ๋นˆ์„ ๊ฐ€์ง)

์ฐธ๊ณ ์ž๋ฃŒ

Last updated

Was this helpful?