JavaRush /Java Blog /Random-KO /์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ. ์†Œ๊ฐœ
Marchello
๋ ˆ๋ฒจ 20
ะกะฐะฝะบั‚-ะŸะตั‚ะตั€ะฑัƒั€ะณ

์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ. ์†Œ๊ฐœ

Random-KO ๊ทธ๋ฃน์— ๊ฒŒ์‹œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค
์•ˆ๋…•ํ•˜์„ธ์š”! JavaRush ๊ด€๋ฆฌ๊ฐ€ ์ƒˆ๋กœ์šด ์ˆ˜์ค€์—์„œ ์ž‘์—…ํ•˜๋Š” ๋™์•ˆ ์ €๋Š” Spring Framework์— ๋Œ€ํ•œ ์ผ๋ จ์˜ ๊ต์œก ๊ธฐ์‚ฌ๋ฅผ ์‹œ์ž‘ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์˜ˆ, ์ธํ„ฐ๋„ท์— ์ด๋ฏธ ์ด ์ฃผ์ œ์— ๊ด€ํ•œ ๋งŽ์€ ์ž๋ฃŒ๊ฐ€ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์ง€๋งŒ ์‹ค์Šต์—์„œ ์•Œ ์ˆ˜ ์žˆ๋“ฏ์ด ๋ชจ๋‘ Hello World ์ˆ˜์ค€์— ์žˆ์Šต๋‹ˆ๋‹ค. ์ €๋Š” ์ฃผ์„์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๋ฐฐ์น˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์•„๋‹ˆ๋ผ ์ด ๋ชจ๋“  ๊ฒƒ์ด "๋‚ด๋ถ€์ ์œผ๋กœ" ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์ด ๊ธ€์€ ์ด๋ฏธ ์–ด๋–ค ๋ฐฉ์‹์œผ๋กœ๋“  ์ด ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•ด๋ณธ ๊ฒฝํ—˜์ด ์žˆ๊ณ  ๊ธฐ๋ณธ ๊ฐœ๋…์— ์ต์ˆ™ํ•œ ์‚ฌ๋žŒ๋“ค์„ ๋Œ€์ƒ์œผ๋กœ ์ž‘์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ.  ์†Œ๊ฐœ - 1

์ปจํ…์ŠคํŠธ๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ์ค‘์ž…๋‹ˆ๋‹ค.

์ด์ œ ๊ธฐ๋ณธ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์ œ ์ƒ๊ฐ์—๋Š” ๊ฐ€์žฅ ์ค‘์š”ํ•œ ์  ์ค‘ ํ•˜๋‚˜๋Š” ์ปจํ…์ŠคํŠธ๊ฐ€ ์–ด๋–ป๊ฒŒ ์„ค์ •๋˜๊ณ  Bean์ด ์ดˆ๊ธฐํ™”๋˜๋Š”์ง€ ์ดํ•ดํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์•„์‹œ ๋‹ค์‹œํ”ผ Spring์ด ์ž‘๋™ํ•˜๊ธฐ ์ „์— ๊ตฌ์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋Œ€ํ™์ˆ˜ ์ด์ „์—๋Š” xml ํŒŒ์ผ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค(์ผ๋ถ€ ํ”„๋กœ์ ํŠธ, ์ฃผ๋กœ ์˜ค๋ž˜๋œ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ์˜ค๋Š˜๋‚ ๊นŒ์ง€ ๊ณ„์† ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค). ๋‹ค์Œ์€ ์ด๋Ÿฌํ•œ ๊ตฌ์„ฑ ํŒŒ์ผ์˜ ์ž‘์€ ์˜ˆ์ž…๋‹ˆ๋‹ค.
<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

   <bean id="helloWorld" class="ru.javarush.HelloWorld">
       <property name="message" value="Hello World!"/>
   </bean>

</beans>
์ „๋ฐ˜์ ์œผ๋กœ ์ด๊ฒƒ์€ ๋‘ ๊ฐœ์˜ ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ๋งŒ๋“ค๊ณ  ์Šคํƒ€ํŠธ์—…์„ ์‹œ์ž‘ํ•˜๊ธฐ์— ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค(์ด๋ฅ™ํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค). ํ•˜์ง€๋งŒ ์ด ๊ตฌ์„ฑ์œผ๋กœ Spring์ด ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๊ฒŒ ๋ ๊นŒ์š”? ๊ทธ๋ฆฌ๊ณ  ์—ฌ๊ธฐ์„œ ์ผ์ด ํฅ๋ฏธ๋กœ์›Œ์ง‘๋‹ˆ๋‹ค. Spring์ด ์šฐ๋ฆฌ์˜ ๊ตฌ์„ฑ์„ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” XmlBeanDefinitionReader. ์ด๊ฒƒ์€ xml์„ ์Šค์บ”(ํŒŒ์‹ฑ)ํ•˜๊ณ  ๊ฑฐ๊ธฐ์— ์ž‘์„ฑํ•œ ๋‚ด์šฉ์„ ๊ธฐ๋ฐ˜์œผ๋กœ BeanDefinition์„ ์ƒ์„ฑํ•˜๋Š” ๋‚ด๋ถ€ Spring ๊ตฌ์„ฑ ์š”์†Œ์ž…๋‹ˆ๋‹ค. BeanDefinitionBean์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๋Š” ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—๋Š” ๋‹ค์Œ์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. ํ•ด๋‹น ํด๋ž˜์Šค(๋นˆ)๊ฐ€ ์ƒ์„ฑ๋˜์–ด์•ผ ํ•˜๋Š” ํด๋ž˜์Šค; ๋ฒ”์œ„; ์ง€์—ฐ ์ดˆ๊ธฐํ™”๊ฐ€ ์„ค์น˜๋˜์–ด ์žˆ๋Š”์ง€ ์—ฌ๋ถ€ ์ด Bean ์ „์— xml์— ์„ค๋ช…๋œ ๋‹ค๋ฅธ ์†์„ฑ๊ณผ ๋‹ค๋ฅธ ์†์„ฑ์„ ์ดˆ๊ธฐํ™”ํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ? ์ˆ˜์‹ ๋œ ๋ชจ๋“  BeanDefinition๋Š” ์— ์ถ”๊ฐ€๋˜๋ฉฐ HashMap, ์—ฌ๊ธฐ์„œ ์‹๋ณ„์ž๋Š” Bean(์‚ฌ์šฉ์ž๊ฐ€ ์„ค์ •ํ•˜๊ฑฐ๋‚˜ Spring์—์„œ ํ• ๋‹นํ•œ)์˜ ์ด๋ฆ„๊ณผ BeanDefinition๊ฐ์ฒด ์ž์ฒด์ž…๋‹ˆ๋‹ค. ๋ชจ๋“  ๊ฒƒ์ด ๋งŒ๋“ค์–ด์ง„ ํ›„ BeanDefinition์ƒˆ๋กœ์šด ์˜์›…์ด ๋ฌด๋Œ€์— ๋“ฑ์žฅํ•ฉ๋‹ˆ๋‹ค - BeanFactory. HashMapโ€™e์ด ๊ฐ์ฒด๋Š” s๋ฅผ ๋ฐ˜๋ณตํ•˜๊ณ  BeanDefinition์ด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋นˆ์„ ์ƒ์„ฑํ•˜์—ฌ IoC ์ปจํ…Œ์ด๋„ˆ์— ๋„ฃ์Šต๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ์—ฌ๊ธฐ์—๋Š” ๋ฏธ๋ฌ˜ํ•œ ์ฐจ์ด๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์‹œ์ž‘๋˜๋ฉด IoC ์ปจํ…Œ์ด๋„ˆ์—๋Š” ์‹ฑ๊ธ€ํ†ค ๋ฒ”์œ„(๊ธฐ๋ณธ์ ์œผ๋กœ ์„ค์ •๋จ)๊ฐ€ ์žˆ๋Š” Bean์ด ํฌํ•จ๋˜๊ณ  ๋‚˜๋จธ์ง€๋Š” ํ•„์š”ํ•  ๋•Œ(ํ”„๋กœํ† ํƒ€์ž…, ์š”์ฒญ, ์„ธ์…˜) ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ์ด์ œ ์•ฝ๊ฐ„์˜ ์—ฌ๋‹ด์œผ๋กœ ๋‹ค๋ฅธ ์บ๋ฆญํ„ฐ์— ๋Œ€ํ•ด ์•Œ์•„ ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

BeanPostProcessor๋ฅผ ๋งŒ๋‚˜๋ณด์„ธ์š”. (BPP)

๋นˆ ํฌ์ŠคํŠธ ํ”„๋กœ์„ธ์„œ์‚ฌ์‹ค ๋นˆ์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ํด๋ž˜์Šค๊ฐ€ ์•„๋‹ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋นˆ์€ ์ธํ”„๋ผ ๋นˆ(Infrastructure Bean)์ด๋ผ๊ณ ๋„ ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ„๋‹จํžˆ ๋งํ•ด์„œ ์ธํ”„๋ผ ๋นˆ์€ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ๋นˆ(์˜ˆ, ๋นˆ์ด ๋„ˆ๋ฌด ๋งŽ์Œ)์„ ๊ตฌ์„ฑํ•˜๋Š” ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค. ์ด์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์•„๋ž˜์—์„œ ์„ค๋ช…ํ•˜๊ฒ ์ง€๋งŒ BPP๊ฐ€ ์ •ํ™•ํžˆ ๋ฌด์—‡์„ ๊ตฌ์„ฑํ•˜๋Š”์ง€ ์ข€ ๋” ๋ช…ํ™•ํ•˜๊ฒŒ ์„ค๋ช…ํ•˜๊ธฐ ์œ„ํ•ด ์˜ˆ๋ฅผ ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๋‹ค๋“ค ์š”์•ฝ์„ ์ž˜ ์•„์‹œ์ฃ  @Autowired? ๋”ฐ๋ผ์„œ AutowiredAnnotationBeanPostProcessor๋ชจ๋“  ํด๋ž˜์Šค๊ฐ€ ์„œ๋กœ ๋‚ด์žฅ๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๊ฒƒ์€ ๊ท€ํ•˜์˜ ์ฑ…์ž„์ž…๋‹ˆ๋‹ค. ์˜๊ตญ์˜

BeanFactory๋กœ ๋Œ์•„๊ฐ€์ž

HashMap์ด์ œ BPP์— ๋Œ€ํ•ด ์•Œ์•˜์œผ๋ฏ€๋กœ ์„ ๋ฐ˜๋ณตํ•  ๋•Œ ๋ชจ๋“  ๊ฐ€ ๋จผ์ € ์ƒ์„ฑ๋˜์–ด ๋ณ„๋„๋กœ ๋ฐฐ์น˜๋œ๋‹ค๋Š” ์ ์„ ๋ช…ํ™•ํžˆ ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค BeanDefinition(IoC ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์•„๋‹˜) BeanPostProcessor. ๊ทธ๋Ÿฐ ๋‹ค์Œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์˜ ์ผ๋ฐ˜ Bean์ด ์ƒ์„ฑ๋˜์–ด IoC ์ปจํ…Œ์ด๋„ˆ์— ๋ฐฐ์น˜๋˜๋ฉฐ ๋ณ„๋„๋กœ ์ง€์—ฐ๋œ BPP๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌ์„ฑ์ด ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ์ผ์–ด๋‚˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. ๊ฐ BPP์—๋Š” 2๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค.
postProcessorBeforeInitialization(Object bean, String beanName);
postProcessorAfterInitialization(Object bean, String beanName);
bin์„ ๋‘ ๋ฒˆ ๋ฐ˜๋ณตํ•ฉ๋‹ˆ๋‹ค. ๋ฉ”์†Œ๋“œ๊ฐ€ ์ฒ˜์Œ ํ˜ธ์ถœ๋  ๋•Œ postProcessorBeforeInitialization์™€ ๋‘ ๋ฒˆ์งธ๋กœ ๋ฉ”์†Œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ postProcessorAfterInitialization. ์™œ ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ํ•„์š”ํ•œ์ง€์— ๋Œ€ํ•œ ์˜๋ฌธ์ด ์ƒ๊ฒผ์Šต๋‹ˆ๋‹ค. ์„ค๋ช…ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์‚ฌ์‹ค์€ ์ผ๋ถ€ ์ฃผ์„(์˜ˆ: @Transactional)์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด Bean์ด ํ”„๋ก์‹œ ํด๋ž˜์Šค๋กœ ๋Œ€์ฒด๋œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ์ˆ˜ํ–‰๋˜๋Š” ์ด์œ ๋ฅผ ์ดํ•ดํ•˜๋ ค๋ฉด ์ž‘๋™ ๋ฐฉ์‹์„ ์•Œ์•„์•ผ ํ•˜๋ฉฐ @Transactional์ด๊ฒƒ์ด ์ž‘๋™ํ•˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. ์ด ์ฃผ์„์œผ๋กœ ํ‘œ์‹œ๋œ ๋ฉ”์„œ๋“œ์— ์ฆ‰์‹œ ๋ช‡ ์ค„์˜ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์–ด๋–ป๊ฒŒ ํ•˜๋‚˜์š”? ๋งž์Šต๋‹ˆ๋‹ค. ํ”„๋ก์‹œ ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑํ•˜๋ฉด ํ•„์š”ํ•œ ์ฝ”๋“œ๊ฐ€ ํ•„์š”ํ•œ ๋ฉ”์„œ๋“œ์— ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค. ์ด์ œ ์ด๋Ÿฐ ์ƒํ™ฉ์„ ์ƒ์ƒํ•ด ๋ณด์„ธ์š”. ์ˆ˜์—…์ด ์žˆ์Šต๋‹ˆ๋‹ค.
class A {
    @Autowired
    private SomeClass someClass;

    @Transactional
    public void method() {
        // ะผะพะดะธั„ะธะบะฐั‚ะพั€ ะดะพัั‚ัƒะฟะฐ ะพะฑัะทะฐั‚ะตะปัŒะฝะพ public
    }
}
์ด ํด๋ž˜์Šค์—๋Š” 2๊ฐœ์˜ ์ฃผ์„ @Autowired๊ณผ @Transactional. ๋‘ ์ฃผ์„ ๋ชจ๋‘ ์„œ๋กœ ๋‹ค๋ฅธ BPP์— ์˜ํ•ด ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค. ๋จผ์ € ์ž‘๋™ํ•˜๋ฉด AutowiredBPP๋ชจ๋“  ๊ฒƒ์ด ๊ดœ์ฐฎ์ง€๋งŒ ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์ด ๋ฌธ์ œ์— ์ง๋ฉดํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์‚ฌ์‹ค ํ”„๋ก์‹œ ํด๋ž˜์Šค๊ฐ€ ์ƒ์„ฑ๋˜๋ฉด ๋ชจ๋“  ๋ฉ”ํƒ€ ์ •๋ณด๊ฐ€ ์†์‹ค๋ฉ๋‹ˆ๋‹ค. ์ฆ‰, @Autowiredํ”„๋ก์‹œ ํด๋ž˜์Šค์˜ ์ฃผ์„์— ๋Œ€ํ•œ ์ •๋ณด๊ฐ€ ์—†์œผ๋ฏ€๋กœ AutowiredBPP์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์šฐ๋ฆฌ ํ•„๋“œ๊ฐ€ someClass๊ฐ’์„ ๊ฐ€์ง€๊ฒŒ ๋˜์–ด nullNPE๋กœ ์ด์–ด์งˆ ๊ฐ€๋Šฅ์„ฑ์ด ๋†’๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๋ฉ”์†Œ๋“œ ํ˜ธ์ถœ ์‚ฌ์ด์— -method๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ํ˜ธ์ถœ postProcessorBeforeInitialization๋œ๋‹ค๋Š” ์ ๋„ ์•Œ์•„๋‘๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค . ์ด๊ฒƒ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋‘ ๋ฒˆ์งธ ์ƒ์„ฑ์ž์ด์ง€๋งŒ ์ฐจ์ด์ ์€ ํ˜„์žฌ ๋ชจ๋“  ์ข…์†์„ฑ์ด ์ด๋ฏธ ํด๋ž˜์Šค์— ํฌํ•จ๋˜์–ด ์žˆ์œผ๋ฉฐ -method์—์„œ ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋‹ค์‹œ ํ•œ ๋ฒˆ ์ปจํ…์ŠคํŠธ ์ดˆ๊ธฐํ™” ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. postProcessorAfterInitializationinitinit
  1. XmlBeanDefinitionReaderxml ๊ตฌ์„ฑ ํŒŒ์ผ์„ ์Šค์บ”ํ•ฉ๋‹ˆ๋‹ค.
  2. ์„(๋ฅผ) ๋งŒ๋“ค์–ด์„œ BeanDefinition๋„ฃ์Šต๋‹ˆ๋‹ค HashMap.
  3. ์˜ค๊ณ  BeanFactory์ด๊ฒƒ์œผ๋กœ๋ถ€ํ„ฐ HashMap๋ชจ๋“  '๋ฅผ ๋ณ„๋„๋กœ ํ•ฉ์‚ฐํ•ฉ๋‹ˆ๋‹ค BeanPostProcessor.
  4. BeanDefinition์—์„œ ๋นˆ์„ ์ƒ์„ฑํ•˜์—ฌ IoC ์ปจํ…Œ์ด๋„ˆ์— ๋ฐฐ์น˜ํ•ฉ๋‹ˆ๋‹ค.
  5. ์—ฌ๊ธฐ์„œ BPP๋Š” ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋Ÿฌํ•œ Bean์„ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  6. ์ค€๋น„๊ฐ€ ๋œ.
์‚ฌ์‹ค ๊ทธ๊ฒŒ ์ „๋ถ€์ž…๋‹ˆ๋‹ค. ๊ธฐ์‚ฌ๊ฐ€ ๋งˆ์Œ์— ๋“ค์—ˆ๊ณ  ๊ทธ๋Ÿฌํ•œ ํŠœํ† ๋ฆฌ์–ผ์„ ๊ณ„์† ์ž‘์„ฑํ•  ๊ฐ€์น˜๊ฐ€ ์žˆ๋Š”์ง€ ์ž‘์„ฑํ•˜์‹ญ์‹œ์˜ค.
์ฝ”๋ฉ˜ํŠธ
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION