STUDY๐Ÿ„

[Spring ๊ธฐ๋ณธ] 4. ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์™€ ์Šคํ”„๋ง ๋นˆ๐Ÿซ›

์ด๋ฆฌ์ญ 2025. 4. 5. 01:52

์•ˆ๋…•ํ•˜์„ธ์š”!

์˜ค๋Š˜๋ถ€ํ„ฐ ๋ณธ๊ฒฉ์ ์œผ๋กœ ์Šคํ”„๋ง์˜ ์„ธ๊ณ„๋กœ ๋“ค์–ด๊ฐ€๋ณผ๊นŒ ํ•ฉ๋‹ˆ๋‹ค.

๊ณ ๊ณ ์”ฝ!!


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

๋จผ์ € ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์ƒ์„ฑ๋˜๋Š” ๊ณผ์ •์„ ์•Œ์•„๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

//์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ ์ƒ์„ฑ
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);

์ €๋ฒˆ ์„น์…˜ ๋งˆ์ง€๋ง‰ ์ฏ”์Œ์— ๋‚˜์™”๋˜ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค.

new๋กœ ํ•ด์„œ AnnotationConfigApplicationContext ์ด๋ฆ„๋„ ๊ธด ์ด ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋ฉด์„œ AppConfig๋ฅผ ํŒŒ๋ผ๋ฏธํ„ฐ(๋งค๊ฐœ๋ณ€์ˆ˜)๋กœ ๋„˜๊ฒผ์Šต๋‹ˆ๋‹ค.

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ฐ˜ํ™˜๊ฐ’์œผ๋กœ ApplicationContext๊ฐ€ ๋‚˜์˜ต๋‹ˆ๋‹ค.

 

์ด ApplicationContext๋ฅผ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋ผ๊ณ  ํ•˜๊ณ , ์ธํ„ฐํŽ˜์ด์Šค์ž…๋‹ˆ๋‹ค.

๋‹คํ˜•์„ฑ์ด ์ ์šฉ๋˜์–ด์žˆ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ด ApplicationContext ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•œ ๊ฒƒ ์ค‘์— ํ•˜๋‚˜๊ฐ€ AnnotationConfigApplicationContext ์ž…๋‹ˆ๋‹ค.

=> AnnotationConfigApplicationContext(AppConfig.class) ์ด ํด๋ž˜์Šค๋Š” ApplicationContext ์ธํ„ฐํŽ˜์ด์Šค์˜ ๊ตฌํ˜„์ฒด

 

์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋Š” XML ๊ธฐ๋ฐ˜์œผ๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ณ , Annotation ๊ธฐ๋ฐ˜์˜ ์ž๋ฐ” ์„ค์ • ํด๋ž˜์Šค๋กœ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

(์š”์ฆ˜์€ XML ๊ธฐ๋ฐ˜์œผ๋กœ ๋งŒ๋“œ๋Š” ๊ฒƒ์„ ์ž˜ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.)

์ €๋ฒˆ ์„น์…˜์—์„œ AppConfig๋ฅผ ์‚ฌ์šฉํ–ˆ๋˜ ๋ฐฉ์‹์ด Annotation ๊ธฐ๋ฐ˜์˜ ์ž๋ฐ” ์„ค์ • ํด๋ž˜์Šค๋กœ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋ฅผ ๋งŒ๋“  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

<์ฐธ๊ณ โœ”๏ธ>
๋” ์ •ํ™•ํžˆ๋Š” ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋ฅผ ๋ถ€๋ฅผ ๋•Œ BeanFactory, ApplicationContext๋กœ ๊ตฌ๋ถ„ํ•ด์„œ ์–˜๊ธฐํ•ฉ๋‹ˆ๋‹ค.
BeanFactory๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ๊ฑฐ์˜ ์—†์œผ๋ฏ€๋กœ, ์ผ๋ฐ˜์ ์œผ๋กœ ApplicationContext๋ฅผ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.
์ด ๋ถ€๋ถ„์€ ๋’ค์—์„œ ๋‹ค๋ฃฐ ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.

 

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

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

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

1. new AnnotationConfigApplicationContext(AppConfig.class)๋ผ๊ณ  ํ•˜๋ฉด์„œ AppConfig์˜ ์ •๋ณด๋ฅผ ์ค๋‹ˆ๋‹ค.

2. ๊ทธ๋Ÿฌ๋ฉด ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ๋”ฑ ๋งŒ๋“ค์–ด์ง‘๋‹ˆ๋‹ค.

    ๊ทธ๋Ÿฐ๋ฐ, ์ด ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ ์•ˆ์—๋Š” ์Šคํ”„๋ง ๋นˆ ์ €์žฅ์†Œ๋ผ๋Š” ๊ฒƒ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

    ๊ทธ๋ž˜์„œ, key๋Š” ๋นˆ ์ด๋ฆ„์ด ๋˜๊ณ , ๊ฐ’์€ ๋นˆ ๊ฐ์ฒด๊ฐ€ ๋˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

    => ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ƒ์„ฑํ•  ๋•Œ๋Š” ๊ตฌ์„ฑ ์ •๋ณด๋ฅผ ์ง€์ •ํ•ด์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์„œ๋Š” AppConfig.class๋ฅผ ๊ตฌ์„ฑ ์ •๋ณด๋กœ ์ง€์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

 

1-1(2). ์Šคํ”„๋ง ๋นˆ ๋“ฑ๋ก๐Ÿซ›

์Šคํ”„๋ง ๋นˆ ๋“ฑ๋ก

์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ๋ณธ์ธ์„ ์ƒ์„ฑํ•˜๋ฉด์„œ ์Šคํ”„๋ง ๋นˆ ์ €์žฅ์†Œ์— ์Šคํ”„๋ง ๋นˆ์„ ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค.

์–ด๋–ป๊ฒŒ ํ•˜๋ƒ๋ฉด...

1. AppConfig.class ์„ค์ • ์ •๋ณด๋ฅผ ๋„˜๊ธด ๊ฒƒ์—์„œ @Bean ๋ถ™์€ ๊ฒƒ์„ ํ•˜๋‚˜์”ฉ ๋ด…๋‹ˆ๋‹ค.

2. ๊ทธ๋ฆฌ๊ณ  @Bean ๋ถ™์€ ๊ฒƒ์„ ๋‹ค ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

   ํ˜ธ์ถœํ•ด๋ณด๋‹ˆ๊นŒ memberService๋ผ๋Š” ๋ฉ”์„œ๋“œ ์ด๋ฆ„์ด ์žˆ๋„ค์š”? ์ด ๋ฉ”์„œ๋“œ ์ด๋ฆ„์„ key(๋นˆ ์ด๋ฆ„)๋กœ ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค.

   ์ด key์— ๋Œ€ํ•œ ๊ฐ’์€ return ํ•ด์„œ new๋กœ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฐ์ฒด๋ฅผ ๋นˆ ๊ฐ์ฒด๋กœ ๋“ฑ๋ก์„ ํ•ด์ค๋‹ˆ๋‹ค. 

3. ์ง€๊ธˆ ๊ทธ๋ฆผ์— ๋‚˜์™€์žˆ๋Š” ๊ฒƒ์€ ์ด 4๊ฐœ๋‹ˆ๊นŒ ์ด 4๊ฐœ๋ฅผ ๋‹ค ๋“ฑ๋กํ•ด์ค๋‹ˆ๋‹ค.

   ๊ทธ๋Ÿฌ๋ฉด newํ•œ ์ธ์Šคํ„ด์Šค ๊ฐ์ฒด 4๊ฐœ๊ฐ€ ๋‹ค ๋“ฑ๋ก์ด ๋˜๊ณ , ์ด๊ฒƒ์„ ์Šคํ”„๋ง ๋นˆ์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

<์ฐธ๊ณ โœ”๏ธ>
- ๋นˆ ์ด๋ฆ„์€ ๋ฒ ์„œ๋“œ ์ด๋ฆ„์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
- ๋นˆ ์ด๋ฆ„์„ ์ง์ ‘ ๋ถ€์—ฌํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
=> @Bean (name = "memberService2")

<์ฃผ์˜!!โš ๏ธ>
๋นˆ ์ด๋ฆ„์€ ํ•ญ์ƒ ๋‹ค๋ฅธ ์ด๋ฆ„์„ ๋ถ€์—ฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
๊ฐ™์€ ์ด๋ฆ„์„ ๋ถ€์—ฌํ•˜๋ฉด, ๋‹ค๋ฅธ ๋นˆ์ด ๋ฌด์‹œ๋˜๊ฑฐ๋‚˜ ๊ธฐ์กด ๋นˆ์„ ๋ฎ์–ด๋ฒ„๋ฆฝ๋‹ˆ๋‹ค.
์ด๋Ÿฌ๋ฉด ์„ค์ •์— ๋”ฐ๋ผ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

 

1-1(3). ์Šคํ”„๋ง ๋นˆ ์˜์กด๊ด€๊ณ„ ์„ค์ • - ์ค€๋น„๐Ÿซ›

์Šคํ”„๋ง ๋นˆ ์˜์กด๊ด€๊ณ„ ์„ค์ • - ์ค€๋น„

์Šคํ”„๋ง ๋นˆ์€ ์ดˆ๋ก์ƒ‰ ํƒ€์›์˜ ๊ทธ๋ฆผ์œผ๋กœ ํ‘œํ˜„ํ•˜๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. (์ฝฉ์ด์–ด์„œ..?ใ…‹ใ…‹ใ…‹๐Ÿซ›)

์ด๋ ‡๊ฒŒ ์ค€๋น„๋ฅผ ํ•ด๋†“๊ณ , ๋‹ค์Œ ๋‹จ๊ณ„๋กœ ๋„˜์–ด๊ฐ€๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

1-1(4). ์Šคํ”„๋ง ๋นˆ ์˜์กด๊ด€๊ณ„ ์„ค์ • - ์™„๋ฃŒ๐Ÿซ›

์Šคํ”„๋ง ๋นˆ ์˜์กด๊ด€๊ณ„ ์„ค์ • - ์™„๋ฃŒ

์˜์กด๊ด€๊ณ„๋ฅผ ๋„ฃ์–ด๋ณผ๊ฑด๋ฐ์š”.

memberService์˜ ์˜์กด๊ด€๊ณ„๋กœ๋Š” memberRepository๋ฅผ ๋„ฃ์–ด์คฌ์Šต๋‹ˆ๋‹ค. (๋นจ๊ฐ„์ƒ‰ ํ™”์‚ดํ‘œ ์ฐธ๊ณ )

์ด๋ ‡๊ฒŒ ์˜์กด๊ด€๊ณ„๊ฐ€ ๋˜๋ฉด new๋กœ MemoryMemberRepository๊ฐ€ ๋ฆฌํ„ด์ด ๋ฉ๋‹ˆ๋‹ค. (์ฝ”๋“œ ์ฐธ๊ณ )

 

๊ทธ ๋‹ค์Œ์— orderService๋ฅผ ๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

orderService๋Š” memberRepository๋„ ์˜์กดํ•˜๊ณ  (๋นจ๊ฐ„์ƒ‰ ํ™”์‚ดํ‘œ), discountPolicy๋„ ์˜์กดํ•ฉ๋‹ˆ๋‹ค (ํŒŒ๋ž€์ƒ‰ ํ™”์‚ดํ‘œ).

๊ทธ๋ž˜์„œ, ์ด discountPolicy ์Šคํ”„๋ง ๋นˆ์€ ์‹ค์ œ๋กœ๋Š” new๋กœ RateDiscountPolicy๊ฐ€ ๋ฆฌํ„ด์ด ๋ฉ๋‹ˆ๋‹ค.

 

๋™์ ์ธ ๊ฐ์ฒด ์ธ์Šคํ„ด์Šค ์˜์กด๊ด€๊ณ„๋ฅผ ์‹ค์ œ๋กœ ์Šคํ”„๋ง์ด ๋‹ค ์—ฐ๊ฒฐํ•ด์ค๋‹ˆ๋‹ค.

๊ทธ๋Ÿผ ์‹ค์ œ๋กœ ์Šคํ”„๋ง ๋นˆ์ด ๋”ฑ ์—ฐ๊ฒฐ์ด ๋ฉ๋‹ˆ๋‹ค.

 

์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋Š” ์„ค์ • ์ •๋ณด๋ฅผ ์ฐธ๊ณ ํ•˜์—ฌ ์˜์กด๊ด€๊ณ„๋ฅผ ์ฃผ์ž…(DI)ํ•ฉ๋‹ˆ๋‹ค.

๋‹จ์ˆœํžˆ ์ž๋ฐ” ์ฝ”๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ ๊ฐ™์ง€๋งŒ ์ฐจ์ด๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ์ฐจ์ด๋Š” ๋’ค์— ์‹ฑ๊ธ€ํ†ค ์ปจํ…Œ์ด๋„ˆ์—์„œ ๋ณผ ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.

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

<์ •๋ฆฌโœ๏ธ>
์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ์„ค์ •(๊ตฌ์„ฑ) ์ •๋ณด๋ฅผ ์ฐธ๊ณ ํ•ด์„œ ์Šคํ”„๋ง ๋นˆ๋„ ๋“ฑ๋กํ•˜๊ณ , ์˜์กด๊ด€๊ณ„๋„ ์„ค์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.
์ด์ œ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

2. ์ปจํ…Œ์ด๋„ˆ์— ๋“ฑ๋ก๋œ ๋ชจ๋“  ๋นˆ ์กฐํšŒ

์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์— ์‹ค์ œ ์Šคํ”„๋ง ๋นˆ๋“ค์ด ์ž˜ ๋“ฑ๋ก๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์ด๊ฑด ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋กœ ํ•œ ๋ฒˆ ์งœ๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์šฐ์„  test์—์„œ hello.core์— beanfind๋ผ๋Š” ํŒจํ‚ค์ง€๋ฅผ ๋งŒ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ , ์ด beanfind๋ผ๋Š” ํŒจํ‚ค์ง€ ์•ˆ์— ApplicationContextInfoTest๋ผ๋Š” ์ž๋ฐ” ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋งŒ๋“ค๋ฉด ์ด๋Ÿฐ ํŒŒ์ผ ๊ตฌ์กฐ๊ฐ€ ๋‚˜์˜ต๋‹ˆ๋‹ค.

 

ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ํ•œ ๋ฒˆ ์งœ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

public class ApplicationContextInfoTest {

    //๋„ˆ๋ฌด ๊ธธ์–ด์„œ ac๋กœ ์ค„์˜€์Šต๋‹ˆ๋‹ค.
    AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);

    @Test
    @DisplayName("๋ชจ๋“  ๋นˆ ์ถœ๋ ฅํ•˜๊ธฐ")
    void findAllBean() {
        //ac.getBeanDefinitionNames(); ๊นŒ์ง€ ์น˜๊ณ  Ctrl + Alt + V ํ•˜๋ฉด ์•ž์— ํƒ€์ž… ํ•˜๊ณ  ๋‚˜์˜ต๋‹ˆ๋‹ค.
        String[] beanDefinitionNames = ac.getBeanDefinitionNames();
        //๋ฆฌ์ŠคํŠธ๋‚˜ ๋ฐฐ์—ด์ด ์žˆ์œผ๋ฉด iteration์ด๋ผ๊ณ  ํ•ด์„œ iter ์น˜๊ณ  Tab ๋ˆ„๋ฅด๋ฉด ๋ฐ‘์— for๋ฌธ์ด ๋‚˜์˜ต๋‹ˆ๋‹ค.
        for (String beanDefinitionName : beanDefinitionNames) {
            Object bean = ac.getBean(beanDefinitionName);
            System.out.println("name = " + beanDefinitionName + " object = " + bean);

        }
    }
}

์ฒซ ๋ฌธ์žฅ๋ถ€ํ„ฐ ์ฐจ๊ทผ์ฐจ๊ทผ ๋ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

ํ•จ์ˆ˜๋ช…์€ ApplicationContextInfoTest๋กœ ์ง€์—ˆ์Šต๋‹ˆ๋‹ค.

public ์จ ์žˆ๋Š”๋ฐ, JUnit5์—์„œ๋ถ€ํ„ฐ๋Š” ์•ž์— public ์•ˆ ๋ถ™ํ˜€๋„ ๋ฉ๋‹ˆ๋‹ค.

(์ƒ๋žต ๊ฐ€๋Šฅํ•œ๋ฐ ์ผ๋‹จ ์ด๊ฑฐ ์–˜๊ธฐํ•˜๋ ค๊ณ  ์ ์–ด๋†“์€ ๊ฒƒ์ž…๋‹ˆ๋‹ค.)

 

AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);๋ฅผ ํ†ตํ•ด์„œ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ƒ์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค. ์œ„์—์„œ๋„ ๋ดค๋˜ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค.

๋ณ€์ˆ˜๋ช…์€ ๋„ˆ๋ฌด ๊ธธ์–ด์„œ ac๋กœ ์ค„์˜€์Šต๋‹ˆ๋‹ค.

 

"๋ชจ๋“  ๋นˆ ์ถœ๋ ฅํ•˜๊ธฐ"๋กœ ํ•ด์„œ findAllBean์œผ๋กœ ํ•จ์ˆ˜ ์ด๋ฆ„์„ ์ง€์–ด๋ณด์•˜์Šต๋‹ˆ๋‹ค.

void ์•ž์— public๋„ ์œ„์—์„œ ์–˜๊ธฐํ•œ ์ด์œ ๋กœ ์ƒ๋žตํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

String[] beanDefinitionNames = ac.getBeanDefinitionNames(); ์ด ์ฝ”๋“œ์—์„œ ์ด ์•ž์— ๋ถ™์€ String ํƒ€์ž….. ์‚ฌ์‹ค ์™œ ์“ฐ์˜€๋Š”์ง€ ๋ชจ๋ฆ…๋‹ˆ๋‹ค.

ac.getBeanDefinitionNames()์น˜๊ณ  Window ๊ธฐ์ค€ Ctrl + Alt + V ์น˜๋ฉด ์œ„์—์ฒ˜๋Ÿผ ํƒ€์ž…์ด ๋‚˜์˜ต๋‹ˆ๋‹ค.

์–ด๋–ค ํƒ€์ž…์ด ๋ฆฌํ„ด ๋˜๋Š”์ง€ ์•Œ์•„๋ณผ ํ•„์š”๊ฐ€ ์—†๋‹ค๋Š” ์žฅ์ ์ด ์žˆ์ฃ .

์œ„์˜ ac.getBeanDefinitionNames()๋Š” ์Šคํ”„๋ง์— ๋“ฑ๋ก๋œ ๋ชจ๋“  ๋นˆ ์ด๋ฆ„์„ ์กฐํšŒํ•ฉ๋‹ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ , ac.getBean()์€ ๋นˆ ์ด๋ฆ„์œผ๋กœ ๋นˆ ๊ฐ์ฒด(์ธ์Šคํ„ด์Šค)๋ฅผ ์กฐํšŒํ•ฉ๋‹ˆ๋‹ค.

 

์•”ํŠผ ์™œ ์•ž์— Object๋ž‘ String์ด ์˜ค๋Š”์ง€๋Š” ์Šคํ”„๋ง์„ ๋งŒ๋“  ์‚ฌ๋žŒ์ด ์ด๋ ‡๊ฒŒ ์„ค๊ณ„๋ฅผ ํ•ด ๋ฒ„๋ฆฐ ๊ฒƒ์ด์–ด์„œ ํ™•์‹คํ•˜๊ฒŒ๋Š” ๋ชจ๋ฅด๊ฒ ์ง€๋งŒ...

getBeanDefinitionNames๋Š” ์ด๋ฆ„๋“ค์ด ์˜ค๊ณ , ์ด๋ฆ„์€ String์ด์ฃ . ์—ฌ๋Ÿฌ ๊ฐœ์˜ String๋“ค์ด๋ผ String ๋ฐฐ์—ด์„ ์‚ฌ์šฉํ•œ ๊ฒƒ์ด ์•„๋‹๊นŒ ์กฐ์‹ฌ์Šค๋ ˆ ์˜ˆ์ธกํ•ด๋ด…๋‹ˆ๋‹ค...

 

๊ทธ ๋‹ค์Œ for๋ฌธ์„ ๋ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์‚ฌ์‹ค ์ด for๋ฌธ... ์œ„์— ๋ฆฌ์ŠคํŠธ๋‚˜ ๋ฐฐ์—ด์ด ์žˆ์œผ๋ฉด iteration์ด๋ผ๊ณ  ํ•ด์„œ iter ์น˜๊ณ , Tab ๋ˆ„๋ฅด๋ฉด ์ด๋ ‡๊ฒŒ for๋ฌธ์ด ๋‚˜์˜ต๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ , Object bean = ac.getBean(beanDefinitionName);๋„ ์œ„์— String๋•Œ์™€ ๊ฐ™์ด Ctrl + Alt + V ์น˜๋ฉด ํƒ€์ž…์„ ์•Œ๋ ค์ค๋‹ˆ๋‹ค.

 

ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋ชจ๋“  ๋นˆ ์ถœ๋ ฅ

์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์— ๋“ฑ๋ก๋œ ๋ชจ๋“  ๋นˆ์ด ์ด๋ ‡๊ฒŒ ์ซ˜๋ผ๋ฝ ์ถœ๋ ฅ์ด ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์œ„์— 5์ค„์€ ๋’ค์—๊ฐ€ ์งค๋ฆฌ๊ธด ํ–ˆ์ง€๋งŒ, ์œ„์— 5์ค„์€ ์Šคํ”„๋ง์ด ๋‚ด๋ถ€์ ์œผ๋กœ ์Šคํ”„๋ง ์ž์ฒด๋ฅผ ํ™•์žฅํ•˜๊ธฐ ์œ„ํ•ด์„œ ์“ฐ๋Š” ๊ธฐ๋ฐ˜ ๋นˆ๋“ค์ž…๋‹ˆ๋‹ค.

์ฐธ๊ณ ๋กœ appConfig๋„ ์Šคํ”„๋ง ๋นˆ์œผ๋กœ ๋“ฑ๋ก์ด ๋ฉ๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ , ์•„๋ž˜ 4์ค„์ด ์ง„์งœ ๋“ฑ๋กํ•œ ์• ๋“ค์ž…๋‹ˆ๋‹ค.

 

๊ทผ๋ฐ, ๋‚ด๋ถ€์ ์ธ ๊ฒƒ๋“ค์ด๋ž‘ ๋‚ด๊ฐ€ ์ง  ์ฝ”๋“œ๋“ค์ด๋ž‘ ์„ž์ด๋ฉด ์ซŒ ๊ทธ๋Ÿด ์ˆ˜ ์žˆ์ž–์•„์š”..ใ…Ž ์•„๋ฌด๋ž˜๋„ ๋ณธ์ธ์ด ์ง  ์ฝ”๋“œ๋งŒ ๋ณด๊ณ  ์‹ถ์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์ €๋Š” ๊ทธ๋ ‡๊ฑฐ๋“ ์š”.

๊ทธ๋ž˜์„œ applicationbean์ด๋ผ๋Š” ๊ฒƒ์„ ํ•œ ๋ฒˆ ์ถœ๋ ฅํ•ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

@Test
    @DisplayName("์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋นˆ ์ถœ๋ ฅํ•˜๊ธฐ")
    void findApplicationBean() {
        String[] beanDefinitionNames = ac.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            BeanDefinition beanDefinition = ac.getBeanDefinition(beanDefinitionName);

            if (beanDefinition.getRole() == BeanDefinition.ROLE_APPLICATION) {
                Object bean = ac.getBean(beanDefinitionName);
                System.out.println("name = " + beanDefinitionName + " object = " + bean);
            }
        }
    }

์œ„์— ์ฝ”๋“œ๋ž‘ ๋น„์Šทํ•œ๋ฐ, ๋”ฑ ํ•œ ์ค„ ๋‹ค๋ฅธ ๋ถ€๋ถ„์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋นˆ์„ ์ถœ๋ ฅํ•˜๊ธฐ ์œ„ํ•ด if๋ฌธ์„ ์‚ฌ์šฉํ•ด์„œ ์—ญํ• ์„ Application์œผ๋กœ ์žก์•˜์Šต๋‹ˆ๋‹ค.

<Role๐Ÿ˜„>
ROLE_APPLICATION: ์ง์ ‘ ๋“ฑ๋กํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋นˆ
ROLE_INFRASTRUCTURE: ์Šคํ”„๋ง์ด ๋‚ด๋ถ€์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋นˆ

 

ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋นˆ ์ถœ๋ ฅ

์ด๋ ‡๊ฒŒ ์ œ๊ฐ€ ์ž‘์„ฑํ•œ ์ฝ”๋“œ๋งŒ ๋‚˜์˜ค๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


3. ์Šคํ”„๋ง ๋นˆ ์กฐํšŒ

3-1. ๊ธฐ๋ณธ

์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์—์„œ ์Šคํ”„๋ง ๋นˆ์„ ์ฐพ๋Š” ๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ ์กฐํšŒ ๋ฐฉ๋ฒ•์€ ac.getBean(๋นˆ ์ด๋ฆ„, ํƒ€์ž…)์ž…๋‹ˆ๋‹ค.

๋นˆ ์ด๋ฆ„์„ ์ƒ๋žตํ•˜๊ณ , ac.getBean(ํƒ€์ž…)์ฒ˜๋Ÿผ ํƒ€์ž…๋งŒ ์ค˜๋„ ๋ฉ๋‹ˆ๋‹ค.

 

๊ทธ๋Ÿฐ๋ฐ, ์กฐํšŒ ๋Œ€์ƒ ์Šคํ”„๋ง ๋นˆ์ด ์—†์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿด ๋•Œ๋Š” ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š”๋ฐ์š”.

NoSuchBeanDefinitionException: No bean named 'xxxxx' available ๋ผ๋Š” ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

 

๊ทธ๋Ÿผ ์ฝ”๋”ฉ์„ ์ง์ ‘ ํ•œ ๋ฒˆ ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋จผ์ €, Test ํŒจํ‚ค์ง€์—์„œ hello.core ์•ˆ์— ์žˆ๋Š” beanfind ํŒจํ‚ค์ง€์— ApplicationContextBasicFindTest ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด์ค๋‹ˆ๋‹ค.

 

์šฐ์„ , ๋นˆ ์ด๋ฆ„์œผ๋กœ ์กฐํšŒํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

class ApplicationContextBasicFindTest {

    AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);

    @Test
    @DisplayName("๋นˆ ์ด๋ฆ„์œผ๋กœ ์กฐํšŒ")
    void findBeanByName() {
        MemberService memberService = ac.getBean("memberService", MemberService.class);
        assertThat(memberService).isInstanceOf(MemberServiceImpl.class);
    }
}

๋งจ ์œ„์— public์€ ์ƒ๋žตํ•˜์˜€์Šต๋‹ˆ๋‹ค.

getBean(๋นˆ ์ด๋ฆ„="memberService", ํƒ€์ž…=MemberService.class)๋ฅผ ํ†ตํ•ด ์กฐํšŒํ–ˆ์Šต๋‹ˆ๋‹ค.

Assertions๋ฅผ ํ†ตํ•ด ๊ฒ€์ฆ์„ ํ•˜์˜€์œผ๋ฉฐ, Static ๋ฉ”์„œ๋“œ ์ถ”๊ฐ€๋ฅผ ํ†ตํ•ด Assertions๋ฅผ ์ƒ๋žตํ•˜์˜€์Šต๋‹ˆ๋‹ค.

isInstanceOf๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ๊ฐ™์€์ง€ ๊ฒ€์ฆํ•  ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

Assertions ๋ถ€๋ถ„์—์„œ isInstanceOf(MemberServiceImpl.class)์—์„œ MemberServiceImpl ๋Œ€์‹ ์— ์ธํ„ฐํŽ˜์ด์Šค์ธ MemberService๊ฐ€ ์™€๋„ ํ…Œ์ŠคํŠธ๋Š” ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

 

ํ…Œ์ŠคํŠธ๋ฅผ ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋นˆ ์ด๋ฆ„์œผ๋กœ ์กฐํšŒ

์„ฑ๊ณต์ ์œผ๋กœ ํ…Œ์ŠคํŠธ๊ฐ€ ๋˜์—ˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์ด๋ฒˆ์—” ์ด๋ฆ„ ์—†์ด ํƒ€์ž…์œผ๋กœ๋งŒ ์กฐํšŒํ•ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

@Test
    @DisplayName("์ด๋ฆ„ ์—†์ด ํƒ€์ž…์œผ๋กœ๋งŒ ์กฐํšŒ")
    void findBeanByType() {
        MemberService memberService = ac.getBean(MemberService.class);
        assertThat(memberService).isInstanceOf(MemberServiceImpl.class);
    }

์•„๊นŒ getBean(ํƒ€์ž…=MemberService.class) ์—ฌ๊ธฐ์—์„œ ์ด๋ฆ„์ด ์ƒ๋žต๋˜์—ˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํƒ€์ž…์œผ๋กœ๋งŒ ์กฐํšŒํ•˜๋Š” ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฆ„์„ ์ ์ง€ ์•Š์€ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์—์„œ๋„ isInstanceOf๋ฅผ ์‚ฌ์šฉํ•ด ๋ฐ์ดํ„ฐ๊ฐ€ ๊ฐ™์€์ง€ ๊ฒ€์ฆ์„ ํ–ˆ์Šต๋‹ˆ๋‹ค.

 

ํ…Œ์ŠคํŠธ๋ฅผ ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์ด๋ฆ„ ์—†์ด ํƒ€์ž…์œผ๋กœ๋งŒ ์กฐํšŒ

์—ญ์‹œ ํ…Œ์ŠคํŠธ๊ฐ€ ์ž˜ ์ง„ํ–‰๋œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์ด๋ ‡๊ฒŒ ์ธํ„ฐํŽ˜์ด์Šค๋กœ ์กฐํšŒ๋ฅผ ํ•˜๋ฉด ์ธํ„ฐํŽ˜์ด์Šค์˜ ๊ตฌํ˜„์ฒด๊ฐ€ ์กฐํšŒ ๋Œ€์ƒ์ด ๋ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ, ์ด๊ฒƒ์„ ๊ตฌ์ฒด ํƒ€์ž…์œผ๋กœ ์กฐํšŒ๋ฅผ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

@Test
    @DisplayName("๊ตฌ์ฒด ํƒ€์ž…์œผ๋กœ ์กฐํšŒ")
    void findBeanByName2() {
        MemberService memberService = ac.getBean("memberService", MemberServiceImpl.class);
        assertThat(memberService).isInstanceOf(MemberServiceImpl.class);
    }

MemberService memberService = ac.getBean("memberService", MemberServiceImpl.class);์—์„œ ํƒ€์ž… ๋ถ€๋ถ„์ธ MemberServiceImpl ๋ถ€๋ถ„์ด ์œ„์—์„œ๋Š” MemberService๋กœ ์ ์—ˆ์ง€๋งŒ, ์—ฌ๊ธฐ์—์„œ๋Š” ๊ตฌํ˜„์ฒด์ธ MemberServiceImpl๋กœ ์ ์—ˆ๋‹ค๋Š” ์ฐจ์ด์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

 

ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๊ตฌ์ฒด ํƒ€์ž…์œผ๋กœ ์กฐํšŒ

์ž˜ ์‹คํ–‰๋˜๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์ด๊ฑธ ์™œ ์–˜๊ธฐํ–ˆ๋Š”์ง€์— ๊ด€ํ•ด์„œ ์„ค๋ช…ํ•˜๊ธฐ ์œ„ํ•ด AppConfig๋กœ ์ด๋™ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

public MemberService memberService() {
        return new MemberServiceImpl(memberRepository());
    }

ํƒ€์ž…์„ MemberService๋กœ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ผญ MemberService๋กœ ํ•ด์•ผํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค.

์™œ๋ƒํ•˜๋ฉด, ์Šคํ”„๋ง ๋นˆ์— ๋“ฑ๋ก๋œ ์ธ์Šคํ„ด์Šค ํƒ€์ž…์„ ๋ณด๊ณ  ๊ฒฐ์ •ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ผญ ์ธํ„ฐํŽ˜์ด์Šค์—ฌ์•ผ ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๊ณ  ๊ทธ ์ธํ„ฐํŽ˜์ด์Šค์˜ ๊ตฌํ˜„์ฒด์—ฌ๋„ ์ƒ๊ด€์ด ์—†์Šต๋‹ˆ๋‹ค.

๋ชฐ๋ก , ๊ตฌ์ฒด์ ์œผ๋กœ ์ ๋Š” ๊ฒƒ์€ ์ข‹์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

ํ•ญ์ƒ ์—ญํ• ๊ณผ ๊ตฌํ˜„์„ ๊ตฌ๋ถ„ํ•ด์•ผํ•˜๊ณ , ์—ญํ• ์— ์˜์กดํ•˜๋„๋ก ํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

์œ„์˜ ์ฝ”๋“œ๋“ค์€ ๊ตฌํ˜„์— ์˜์กดํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

 

ํ•ญ์ƒ ์ฝ”๋“œ๋ฅผ ๊ตฌํ˜„ํ•  ๋•Œ๋Š” ์‹คํŒจํ•˜๋Š” ์ฝ”๋“œ๋„ ๋งŒ๋“ค์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

@Test
    @DisplayName("๋นˆ ์ด๋ฆ„์œผ๋กœ ์กฐํšŒ")
    void findBeanByNameX() {
        //ac.getBean("XXXXX", MemberService.class);
        MemberService XXXXX = ac.getBean("XXXXX", MemberService.class);
    }

์šฐ์„  ๊ฒ€์ฆ๊ณผ์ • ์—†์ด ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์‹ค์ œ ์ €ํฌ๊ฐ€ ๊ตฌํ˜„ํ•˜์ง€ ์•Š์€ ์ด๋ฆ„์ธ XXXXX๋ฅผ ์กฐํšŒํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๊ณผ์—ฐ ๊ฒฐ๊ณผ๋Š” ์–ด๋–ป๊ฒŒ ๋‚˜์˜ฌ๊นŒ์š”?

๋นˆ ์ด๋ฆ„์œผ๋กœ ์กฐํšŒ ์‹คํŒจํ•˜๋Š” ํ…Œ์ŠคํŠธ

์‹คํŒจํ•ฉ๋‹ˆ๋‹ค.

NoSuchBeanDefinitionException์ด๋ผ๋Š” ์˜ˆ์™ธ๊ฐ€ ํ„ฐ์ง€๋ฉด์„œ XXXXX๋ผ๋Š” ์ด๋ฆ„์˜ ๋นˆ์ด ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ๋‹น์—ฐํ•œ ์‚ฌ์‹ค์ด์ฃ . ์ €ํฌ๋Š” ์ด๋Ÿฐ๊ฑฐ ๊ตฌํ˜„ํ•œ ์ ์ด ์—†์œผ๋‹ˆ๊นŒ์š”~~

 

์ด๋ฒˆ์—๋Š” ๊ฒ€์ฆ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ด์„œ ๊ฒ€์ฆ์„ ํ•ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

@Test
    @DisplayName("๋นˆ ์ด๋ฆ„์œผ๋กœ ์กฐํšŒ")
    void findBeanByNameX() {
        //ac.getBean("XXXXX", MemberService.class);
        //MemberService XXXXX = ac.getBean("XXXXX", MemberService.class);
        Assertions.assertThrows(NoSuchBeanDefinitionException.class, 
                () -> ac.getBean("XXXXX", MemberService.class);
    }

์œ„์˜ Assertions๋Š” ํ‰์ƒ์‹œ์˜ Assertions๊ณผ ๋‹ฌ๋ฆฌ JUnit์˜ Assertions์ž…๋‹ˆ๋‹ค.

assertThrows๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” JUnit๊ฑฐ๋กœ ํ•ด์•ผํ•˜๋”๋ผ๊ตฌ์š”.

assertThrows๋Š” ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋  ๋•Œ, ์™ผ์ชฝ ์ธ์ž๋กœ ๋„ฃ์€ ์—๋Ÿฌ Exception์ด ํ„ฐ์ง€๋Š”์ง€ ๊ฒ€์‚ฌํ•˜๋Š” ๋ฉ”์„œ๋“œ ์ž…๋‹ˆ๋‹ค.

์œ„์—์ฒ˜๋Ÿผ ๋˜‘๊ฐ™์ด static import๋ฅผ ํ•ด์„œ Assertions๋ฅผ ์ƒ๋žตํ•ด๋„ ๋ฉ๋‹ˆ๋‹ค.

์—๋Ÿฌ๊ฐ€ ํ„ฐ์ง€๋ฉด ํ…Œ์ŠคํŠธ๊ฐ€ ์„ฑ๊ณตํ•ฉ๋‹ˆ๋‹ค.

 

ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์—๋Ÿฌ๊ฐ€ ํ„ฐ์ ธ์•ผ ํ…Œ์ŠคํŠธ ์„ฑ๊ณต

์—๋Ÿฌ๊ฐ€ ํ„ฐ์ ธ์„œ ํ…Œ์ŠคํŠธ๊ฐ€ ์„ฑ๊ณตํ–ˆ์Šต๋‹ˆ๋‹ค.

 

๊ธฐ์–ตํ•ด์•ผ ํ•  ๊ฒƒ์€ ๊ตฌ์ฒดํƒ€์ž…์œผ๋กœ ๊ตฌํ˜„ํ•˜๋ฉด ์œ ์—ฐ์„ฑ์ด ๋–จ์–ด์ง„๋‹ค๋Š”๊ฑฐ...

์™ ๋งŒํ•˜๋ฉด ์—ญํ• (์ธํ„ฐํŽ˜์ด์Šค)๋กœ ํ•˜์„ธ์š”~~

3-2. ๋™์ผํ•œ ํƒ€์ž…์ด ๋‘˜ ์ด์ƒ

ํƒ€์ž…์œผ๋กœ ์กฐํšŒ๋ฅผ ํ•  ๋•Œ, ๊ฐ™์€ ํƒ€์ž…์˜ ์Šคํ”„๋ง ๋นˆ์ด 2๊ฐœ ์ด์ƒ์ด๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์–ด? ๋ญ˜ ์„ ํƒํ•ด์•ผํ•˜์ง€..??

์ด ๋•Œ๋Š” ๋นˆ ์ด๋ฆ„์„ ์ง€์ •ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

ac.getBeansOfType()์„ ์‚ฌ์šฉํ•˜๋ฉด ํ•ด๋‹น ํƒ€์ž…์˜ ๋ชจ๋“  ๋นˆ์„ ์กฐํšŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

ํ•œ ๋ฒˆ ์กฐํšŒ๋ฅผ ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์šฐ์„ , test ํŒจํ‚ค์ง€์—์„œ hello.core์˜ beanfind ํŒจํ‚ค์ง€์—์„œ ApplicationContextSameBeanFindTest๋ผ๋Š” ์ž๋ฐ” ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด์ค๋‹ˆ๋‹ค.

public class ApplicationContextSameBeanFindTest {

    AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(SameBeanConfig.class);
    
    @Test
    @DisplayName("ํƒ€์ž…์œผ๋กœ ์กฐํšŒ ์‹œ ๊ฐ™์€ ํƒ€์ž…์ด ๋‘˜ ์ด์ƒ ์žˆ์œผ๋ฉด ์ค‘๋ณต ์˜ค๋ฅ˜ ๋ฐœ์ƒ")
    void findBeanByTypeDuplicate() {
        MemberRepository bean = ac.getBean(MemberRepository.class);
    }
    //static: ์ด ํด๋ž˜์Šค ์•ˆ์—์„œ๋งŒ ์‚ฌ์šฉํ•˜๋ ค๊ณ  static ์‚ฌ์šฉ
    @Configuration
    static class SameBeanConfig {
        
        //๋นˆ ์ด๋ฆ„์ด ๋‹ค๋ฅธ๋ฐ ๊ฐ์ฒด ์ธ์Šคํ„ด์Šค ํƒ€์ž…์ด ๊ฐ™์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
        @Bean
        public MemberRepository memberRepository1() {
            return new MemoryMemberRepository();
        }
        
        @Bean
        public MemberRepository memberRepository2() {
            return new MemoryMemberRepository();
        }
    }
}

AppConfig๋ฅผ ๊ท€์ฐฎ๊ฒŒ ๋˜ ์† ๋Œ€๊ธฐ ๋ญ์‹œ๊ธฐํ•˜๋‹ˆ๊นŒ ์ด ํด๋ž˜์Šค ์•ˆ์—์„œ SameBeanConfig๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.

์šฐ์„  ํ˜ธ์ถœํ•˜๋Š” ๋ฐฉ์‹์€ ์œ„์—์„œ ํ–ˆ๋˜ ๊ฑฐ๋ž‘ ๋น„์Šทํ•ฉ๋‹ˆ๋‹ค.

ac.getBean(MemberRepository.class);๋ฅผ ํ•ด์„œ MemberRepository.class์˜ ๋นˆ์„ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

 

๊ทธ๋Ÿฐ๋ฐ, ์œ„์—์™€ ์ฐจ์ด์ ์€ ๋ฐ‘์— SameBeanConfig๋ฅผ ๋งŒ๋“ค์–ด์„œ ์ด AppConfig๋ฅผ ์ด์šฉํ–ˆ๊ณ , ์—ฌ๊ธฐ ํด๋ž˜์Šค ์•ˆ์— memberRepository1, memberRepository2 2๊ฐœ์˜ ๋นˆ(๋นˆ ์ด๋ฆ„)์„ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.

SameBeanConfig ํด๋ž˜์Šค๋Š” ์ด ํด๋ž˜์Šค ์•ˆ์—์„œ๋งŒ ์‚ฌ์šฉํ•  ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— static์„ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

์—ฌ๊ธฐ ์•ˆ์—์„œ ํƒ€์ž…์€ ์ค‘๋ณต๋œ MemberRepository์ž…๋‹ˆ๋‹ค.

 

<๊ณผ์ •>

1. ์ด๋ ‡๊ฒŒ ๋˜๋ฉด ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ๋œฐ ๋•Œ, ์ด SameBeanConfig๋งŒ ๊ฐ€์ง€๊ณ  ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

2. ์—ฌ๊ธฐ์—๋Š” ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์Šคํ”„๋ง ๋นˆ memberRepository1, memberRepository2 2๊ฐœ๋ฅผ ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค.

3. ์ด๊ฒƒ์„ ๋Œ๋ ค๋ณด๋ฉด memberRepository๊ฐ€ 2๊ฐœ๊ฐ€ ํŠ€์–ด๋‚˜์˜ฌ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

    2๊ฐœ ๋‹ค ํƒ€์ž…์ด MemberRepository๋กœ ์ค‘๋ณต๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

4. ๊ทธ๋Ÿผ ์Šคํ”„๋ง ์ž…์žฅ์—์„  ๋ญ˜ ์„ ํƒํ•ด์•ผํ•˜์ง€..? ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๊ณ  NoUniqueBeanDefinitionException์ด๋ผ๋Š” ์˜ˆ์™ธ๊ฐ€ ํ„ฐ์งˆ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋™์ผํ•œ ํƒ€์ž…์ด ๋‘˜ ์ด์ƒ

์œ„์—์„œ ์–˜๊ธฐํ•œ ๊ทธ๋Œ€๋กœ๋„ค์š”. ์˜ˆ์™ธ๊ฐ€ ํ„ฐ์กŒ์Šต๋‹ˆ๋‹ค.

ํ…Œ์ŠคํŠธ ํ•ด๋ณด๊ณ  ์‹คํŒจ ๊ฒฐ๊ณผ ์ซ˜๋ผ๋ฝ ๋ด๋ณด๋ฉด ์–ด๋””์„œ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ฒผ๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์นœ์ ˆํ•˜๊ฒŒ memberRepository1, memberRepository2 ์ค‘ ๋ญ˜ ์„ ํƒํ•ด์•ผํ• ์ง€ ๋ชจ๋ฅด๊ฒ ๋‹ค ๋Œ€์ถฉ ์ด๋Ÿฐ ๋‰˜์•™์Šค๋กœ ์˜ค๋ฅ˜๊ฐ€ ๋œจ๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

ํ…Œ์ŠคํŠธ์˜ ์™„์„ฑ ๋‹จ๊ณ„๋Š” ๊ฒ€์ฆ ๋‹จ๊ณ„์ด๊ธฐ ๋•Œ๋ฌธ์— Assertions๋ฅผ ๋งˆ์ € ์ถ”๊ฐ€ํ•ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 @Test
    @DisplayName("ํƒ€์ž…์œผ๋กœ ์กฐํšŒ ์‹œ ๊ฐ™์€ ํƒ€์ž…์ด ๋‘˜ ์ด์ƒ ์žˆ์œผ๋ฉด ์ค‘๋ณต ์˜ค๋ฅ˜ ๋ฐœ์ƒ")
    void findBeanByTypeDuplicate() {
        //MemberRepository bean = ac.getBean(MemberRepository.class);
        assertThrows(NoUniqueBeanDefinitionException.class,
                () -> ac.getBean(MemberRepository.class));
    }

์œ„์—์ฒ˜๋Ÿผ ์—๋Ÿฌ ๊ด€๋ จ์ด๊ธฐ ๋•Œ๋ฌธ์— JUnit์˜ Assertions๋ฅผ ์‚ฌ์šฉํ–ˆ๊ณ , ๊ฑฐ๊ธฐ์„œ assertThrow๋ฅผ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

static import ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์ „์—๋„ ์–˜๊ธฐํ–ˆ์—ˆ๋Š”๋ฐ, assertThrows๋งŒ ์žˆ๋Š” ์ƒํƒœ์—์„œ ๋นจ๊ฐ„์ƒ‰์œผ๋กœ ๋œจ๋ฉด ๊ฑฐ๊ธฐ์„œ ์ € static ๋ฉ”์„œ๋“œ ๊ฐ€์ ธ์˜ค๊ธฐ๋ฅผ ๋ˆ„๋ฅด๊ฑฐ๋‚˜ Assertions์—์„œ Alt+Enter๋ฅผ ์น˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

์ค‘๋ณต ์˜ˆ์™ธ์ด๊ธฐ ๋•Œ๋ฌธ์— ์œ„์—์„œ ์–˜๊ธฐํ•œ NoUniqueBeanDefinitionException์„ ์‚ฌ์šฉํ–ˆ๊ณ , ํƒ€์ž…์€ MemberReporitory์ด๊ธฐ์— MemberRepository.class๋ฅผ ์ ์–ด์คฌ์Šต๋‹ˆ๋‹ค.

 

ํ…Œ์ŠคํŠธ๋ฅผ ๋‹ค์‹œ ์‹คํ–‰ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์˜ˆ์™ธ๊ฐ€ ํ„ฐ์ ธ์•ผ ์„ฑ๊ณตํ•˜๋Š” ๋กœ์ง์ž…๋‹ˆ๋‹ค.

์—๋Ÿฌ๊ฐ€ ํ„ฐ์ ธ์•ผ ํ…Œ์ŠคํŠธ ์„ฑ๊ณต

์—ญ์‹œ๋‚˜ ํ…Œ์ŠคํŠธ ์„ฑ๊ณตํ–ˆ์Šต๋‹ˆ๋‹ค.

 

๊ทธ๋Ÿผ ๋นˆ ์ด๋ฆ„ ์ง€์ •์„ ํ†ตํ•ด ์˜ˆ์™ธ ์ƒํ™ฉ์„ ํ•ด๊ฒฐํ•ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

๋˜ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์งœ๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

@Test
    @DisplayName("ํƒ€์ž…์œผ๋กœ ์กฐํšŒ ์‹œ ๊ฐ™์€ ํƒ€์ž…์ด ๋‘˜ ์ด์ƒ ์žˆ์œผ๋ฉด ๋นˆ ์ด๋ฆ„ ์ง€์ •์„ ํ†ตํ•ด ํ•ด๊ฒฐ")
    void findBeanByName() {
        MemberRepository memberRepository = ac.getBean("memberRepository1", MemberRepository.class);
        assertThat(memberRepository).isInstanceOf(MemberRepository.class);
    }

๋นˆ ์ด๋ฆ„์„ memberRepository1์œผ๋กœ ์ง€์ •ํ•ด์„œ ํ•ด๊ฒฐ์„ ์‹œ๋„ํ–ˆ์Šต๋‹ˆ๋‹ค.

isInstanceOf๋Š” ์œ„์—์„œ๋„ ์„ค๋ช…ํ–ˆ๋‹ค์‹œํ”ผ ๋ฐ์ดํ„ฐ๊ฐ€ ๊ฐ™์€์ง€ ๊ฒ€์ฆํ•  ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

assertThat(memberRepository)๋ฅผ ์น˜๊ณ ์„œ Alt+Enter๋ฅผ ์น˜๊ณ  static import๋ฅผ ํ•  ๋•Œ, ์‚ฌ์ง„์ฒ˜๋Ÿผ 1๋ฒˆ์งธ ๊ฒƒ์„ ๊ณ ๋ฅด๋ฉด ๋ฉ๋‹ˆ๋‹ค.

 

ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋นˆ ์ด๋ฆ„ ์ง€์ •์„ ํ†ตํ•ด ๊ฐ™์€ ํƒ€์ž… ์ค‘๋ณต ํ˜ธ์ถœ ํ•ด๊ฒฐ

 

์ด๋ฒˆ์—๋Š” ํŠน์ • ์ž‘์—…์„ ๋ชจ๋‘ ์กฐํšŒํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

@Test
    @DisplayName("ํŠน์ • ํƒ€์ž…์„ ๋ชจ๋‘ ์กฐํšŒํ•˜๊ธฐ")
    void findAllBeanByType() {
        //String=Key, MemberRepository=Value
        Map<String, MemberRepository> beansOfType = ac.getBeansOfType(MemberRepository.class);
        for (String key : beansOfType.keySet()) {
            System.out.println("key = " + key + " value = " + beansOfType.get(key));
        }
        System.out.println("beansOfType = " + beansOfType);
        assertThat(beansOfType.size()).isEqualTo(2);
    }

์Šคํ”„๋ง์—์„œ getBeansOfType() ํ•จ์ˆ˜์˜ Returnํ˜•์„ Map์œผ๋กœ ๊ตฌํ˜„ํ•ด๋†จ๊ธฐ ๋•Œ๋ฌธ์— Map ํ•จ์ˆ˜๊ฐ€ ์‚ฌ์šฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๋˜, for (String key : beansOfType.keySet()) ์—ฌ๊ธฐ๋Š” beansOfType ๋ณ€์ˆ˜๊ฐ€ Map<String, MemberRepository>๋ผ๋Š” ํƒ€์ž…์ด์—ˆ๋Š”๋ฐ, ์—ฌ๊ธฐ์„œ keySet()์„ ํ•˜๋ฉด <String, MemberRepository>์—์„œ์˜ ์•ž ๋ฐ์ดํ„ฐ์ธ String ๋ฐ์ดํ„ฐ๋“ค๋งŒ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๋” ์‰ฝ๊ฒŒ ์„ค๋ช…ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

beansOfType์ด๋ผ๋Š” ๋ณ€์ˆ˜๋Š” ์œ„์˜ ์‚ฌ์ง„๊ณผ ๊ฐ™์ด 2๊ฐœ์˜ ๊ฐ’์ด ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐ๊ฐ์˜ ํ•˜๋‚˜ ๊ฐ’์ด String, MemberRepository ํ˜•์˜ ๋ฐ์ดํ„ฐ 2๊ฐœ๋ฅผ ๊ฐ–๊ณ  ์žˆ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

.keySet์„ ํ•˜๋ฉด ์•ž์ชฝ์— ์žˆ๋Š” key ๊ฐ’๋“ค๋กœ๋งŒ ํ•ด์„œ ๋ฐฐ์—ด์„ ๋งŒ๋“ค์–ด์ค๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋ฉด for๋ฌธ์„ ํ†ตํ•ด ๋นˆ ์ด๋ฆ„์„ ํ•˜๋‚˜ํ•˜๋‚˜ ์ถœ๋ ฅํ•ด์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ , .size๋Š” ์‚ฌ์ง„์ฒ˜๋Ÿผ Map์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ช‡ ๊ฐœ๊ฐ€ ์žˆ๋‚˜ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

MemoryMemberRepository์™€ DbMemberRepository 2๊ฐœ๊ฐ€ ๋‚˜์™€์•ผ ํ•˜๊ธฐ์—,

2๊ฐœ๊ฐ€ ๋งž๊ฒŒ ๋‚˜์˜ค๋Š”์ง€ Assertions์˜ assertThat์œผ๋กœ ํ™•์ธํ•ด์ฃผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค,

 

Q. ๊ทธ๋Ÿผ ์—ฌ๊ธฐ์„œ ์งˆ๋ฌธ! ๋ฐฐ์—ด๊ณผ Map ํ•จ์ˆ˜์˜ ์ฐจ์ด์ ์€ ๋ญ˜๊นŒ์š”?

๋ฐฐ์—ด

๋ฐฐ์—ด์€ ์‚ฌ์ง„์ฒ˜๋Ÿผ ๋ฐ์ดํ„ฐ ํ•˜๋‚˜ ๋‹น ํ•œ ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทผ๋ฐ, Map์€ ํ•œ ๋ฐ์ดํ„ฐ ๋‹น key์™€ value๋ผ๋Š” 2๊ฐœ์˜ ๊ฐ’์œผ๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ์Šต๋‹ˆ๋‹ค.

์‚ฌ์‹ค ๊ทผ๋ฐ ๋ฐฐ์—ด๊ณผ Map์€ ๋น„์Šทํ•ฉ๋‹ˆ๋‹ค.

Map ํ•จ์ˆ˜๋Š” Key์™€ Value๋ฅผ ํ•œ ์Œ์œผ๋กœ ์ €์žฅํ•˜๋Š” ๊ฐ์ฒด๊ณ , ๋ฐฐ์—ด์€ ํ•˜๋‚˜ํ•˜๋‚˜์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๋Š” ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค.

๋‘˜ ๋‹ค ์ €์žฅํ•˜๋Š” ์• ๋“ค์ด์—์š”~~

 

๊ทธ๋Ÿผ ๋‹ค์‹œ ๋ณธ๋ก ์œผ๋กœ ๋“ค์–ด๊ฐ€์„œ... ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

ํŠน์ • ํƒ€์ž…์„ ๋ชจ๋‘ ์กฐํšŒํ•˜๊ธฐ

ํ…Œ์ŠคํŠธ๊ฐ€ ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

3-3. ์ƒ์† ๊ด€๊ณ„

์—ฌ๊ธฐ๊ฐ€ ์Šคํ”„๋ง ๋นˆ ์กฐํšŒ ์ค‘์— ์ œ์ผ ์ค‘์š”ํ•œ ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค.

๋ถ€๋ชจ ํƒ€์ž…์œผ๋กœ ์กฐํšŒํ•˜๋ฉด, ์ž์‹ ํƒ€์ž…๋„ ํ•จ๊ป˜ ์กฐํšŒ๋ฉ๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ, ๋ชจ๋“  ์ž๋ฐ” ๊ฐ์ฒด์˜ ์ตœ๊ณ  ๋ถ€๋ชจ์ธ Object ํƒ€์ž…์œผ๋กœ ์กฐํšŒํ•˜๋ฉด ๋ชจ๋“  ์Šคํ”„๋ง ๋นˆ์„ ์กฐํšŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

(๋ˆˆ์—๋Š” ์•ˆ ๋ณด์ด์ง€๋งŒ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋‹ค extends Object๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.)

Test ํŒจํ‚ค์ง€์˜ hello.core ์•ˆ์— ์žˆ๋Š” beanfind ํŒจํ‚ค์ง€์— ApplicationContextExtendsFindTest ์ž๋ฐ” ํด๋ž˜์Šค๋ฅผ ์ถ”๊ฐ€ํ•ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

@Configuration
    static class TestConfig {
        @Bean
        public DiscountPolicy rateDiscountPolicy() {
            return new RateDiscountPolicy();
        }
        
        @Bean
        public DiscountPolicy FixDiscountPolicy() {
            return new FixDiscountPolicy();
        }
    }

์œ„์—์ฒ˜๋Ÿผ AppConfig ๊ฑด๋“ค๊ธฐ ์ซŒ ๊ท€์ฐฎ์•„์ง€๊ธฐ ๋•Œ๋ฌธ์— ์ด ํด๋ž˜์Šค ์•ˆ์— ๋”ฐ๋กœ ํ…Œ์ŠคํŠธ Config๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

๋ณด๋ฉด ํƒ€์ž…์€ DiscountPolicy๋กœ ๊ฐ™์Šต๋‹ˆ๋‹ค. ํƒ€์ž…์ด ์ค‘๋ณต๋˜์ฃ .

 

DiscountPolicy ํƒ€์ž… ์ž๋ฆฌ์— ์‚ฌ์‹ค ๊ฐ๊ฐ RateDiscountPolicy์™€ FixDiscountPolicy๊ฐ€ ์™€๋„ ๋ฉ๋‹ˆ๋‹ค.

๊ทผ๋ฐ, ์™œ DiscountPolicy๋กœ ์ผ์„๊นŒ์š”?

๊ทธ ์ด์œ ๋Š” ์—ญํ• ๊ณผ ๊ตฌํ˜„์„ ํ•ญ์ƒ ์ชผ๊ฐœ์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๊ตฌ์ฒดํ™”๊ฐ€ ์•„๋‹Œ ์ถ”์ƒํ™”๋กœ ํ•ด์•ผ ์˜์กด๊ด€๊ณ„ ์ฃผ์ž…์„ ํ•  ๋•Œ๋„ ํ›จ์”ฌ ์ฝ”๋“œ๊ฐ€ ๋ณด๊ธฐ ์ข‹์•„์ง€๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

๋ชฐ๋ก , ๊ตฌ์ฒดํ™” ํƒ€์ž…์„ ์จ๋„ ๋ฌธ์ œ๋Š” ์—†์Šต๋‹ˆ๋‹ค.

 

ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ๋งˆ์ € ์งœ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

public class ApplicationContextExtendsFindTest {

    AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();

    @Test
    @DisplayName("๋ถ€๋ชจ ํƒ€์ž…์œผ๋กœ ์กฐํšŒ ์‹œ, ์ž์‹์ด ๋‘˜ ์ด์ƒ ์žˆ์œผ๋ฉด ์ค‘๋ณต ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.")
    void findBeanByParentTypeDuplicate() {
        //DiscountPolicy bean = ac.getBean(DiscountPolicy.class);
        assertThrows(NoUniqueBeanDefinitionException.class,
                () -> ac.getBean(DiscountPolicy.class));
    }

    @Configuration
    static class TestConfig {
        @Bean
        public DiscountPolicy rateDiscountPolicy() {
            return new RateDiscountPolicy();
        }

        @Bean
        public DiscountPolicy FixDiscountPolicy() {
            return new FixDiscountPolicy();
        }
    }

"๋ถ€๋ชจ ํƒ€์ž…์œผ๋กœ ์กฐํšŒ ์‹œ, ์ž์‹์ด ๋‘˜ ์ด์ƒ ์žˆ์œผ๋ฉด ์ค‘๋ณต ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค"์— ๊ด€ํ•œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค.

์œ„์—์ฒ˜๋Ÿผ ์ค‘๋ณต ์˜ˆ์™ธ์ด๊ธฐ์— NoUniqueBeanDefinitionException์„ ์‚ฌ์šฉํ–ˆ๊ณ , ๊ทธ๋Ÿฌ๊ธฐ์— Assertions์—์„œ assertThrows๋ฅผ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

(๊ฒ€์ฆ ๋‹จ๊ณ„ ์ง€์šฐ๊ณ  ์ฃผ์„์ฒ˜๋ฆฌ ๋˜์–ด์žˆ๋Š” ๋ถ€๋ถ„ ํ™œ์„ฑํ™” ํ•˜๋ฉด ์‹ค์ œ๋กœ NoUniqueBeanDefinitionException์ด๋ผ๋Š” ์˜ค๋ฅ˜๊ฐ€ ๋œน๋‹ˆ๋‹ค.)

 

ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋ถ€๋ชจ ํƒ€์ž…์œผ๋กœ ์กฐํšŒ ์‹œ, ์ž์‹์ด ๋‘˜ ์ด์ƒ ์žˆ์œผ๋ฉด ์ค‘๋ณต ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒ

NoUniqueBeanDefinitionException ์˜ˆ์™ธ๊ฐ€ ํ„ฐ์ ธ์•ผ ํ…Œ์ŠคํŠธ๊ฐ€ ์„ฑ๊ณตํ•˜๋Š” ๋กœ์ง์ธ๋ฐ, ์—ญ์‹œ๋‚˜ ์„ฑ๊ณตํ–ˆ์Šต๋‹ˆ๋‹ค.

 

์ด๊ฑธ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋นˆ ์ด๋ฆ„์„ ์ง€์ •ํ•ด๋ณด๋Š” ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ๋งŒ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

@Test
    @DisplayName("๋ถ€๋ชจ ํƒ€์ž…์œผ๋กœ ์กฐํšŒ ์‹œ, ์ž์‹์ด ๋‘˜ ์ด์ƒ ์žˆ์œผ๋ฉด ๋นˆ ์ด๋ฆ„์„ ์ง€์ •ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.")
    void findBeanByParentTypeBeanName() {
        DiscountPolicy rateDiscountPolicy = ac.getBean("rateDiscountPolicy", DiscountPolicy.class);
        assertThat(rateDiscountPolicy).isInstanceOf(RateDiscountPolicy.class);
    }

๋นˆ ์ด๋ฆ„์„ ์ง€์ •ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ”๋กœ ๊ฒ€์ฆ๋‹จ๊ณ„๋ฅผ ํ•ด๋„ ์˜ค๋ฅ˜๊ฐ€ ๋‚˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. (์ฃผ์„ ๋”ฐ์œˆ ์—†๋”ฐ)

๋ถ€๋ชจ ํƒ€์ž…์œผ๋กœ ์กฐํšŒ ์‹œ, ์ž์‹์ด ๋‘˜ ์ด์ƒ ์žˆ์œผ๋ฉด ๋นˆ ์ด๋ฆ„์„ ์ง€์ •

์—ญ์‹œ ํ…Œ์ŠคํŠธ๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ์ž‘๋™๋œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๋นˆ ์ด๋ฆ„ ์ง€์ • ๋ง๊ณ ๋„ ๋ถ€๋ชจ ํƒ€์ž…์œผ๋กœ ์กฐํšŒ ์‹œ, ์ž์‹์ด ๋‘˜ ์ด์ƒ ์žˆ์œผ๋ฉด ์ค‘๋ณต ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์˜ ํ•ด๊ฒฐ์ ์€ ๋˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํŠน์ • ํ•˜์œ„ ํƒ€์ž…์œผ๋กœ ์กฐํšŒํ•˜๋Š” ๊ฒƒ์ธ๋ฐ์š”. ๊ทผ๋ฐ, ์ด ๋ฐฉ๋ฒ•์€ ์ข‹์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์™ ์ง€๋Š” ๊ตฌํ˜„๊ณผ ์—ญํ• ... ์ƒ๊ฐํ•˜๋ฉด ๋˜๊ฒ ์ฃ ?

@Test
    @DisplayName("ํŠน์ • ํ•˜์œ„ ํƒ€์ž…์œผ๋กœ ์กฐํšŒ")
    void findBeanBySubType() {
        RateDiscountPolicy bean = ac.getBean(RateDiscountPolicy.class);
        assertThat(bean).isInstanceOf(RateDiscountPolicy.class);
    }

ํŠน์ • ํ•˜์œ„ ํƒ€์ž…์œผ๋กœ ์กฐํšŒํ•˜๋Š” ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋‹จ์ˆœํ•˜๊ฒŒ ํ•˜๋‚˜๋งŒ ์žˆ๊ฒ ์ฃ ?

 

ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

ํŠน์ • ํ•˜์œ„ ํƒ€์ž…์œผ๋กœ ์กฐํšŒ

ํ…Œ์ŠคํŠธ๊ฐ€ ์„ฑ๊ณตํ–ˆ์Šต๋‹ˆ๋‹ค.

์–ด์ฐจํ”ผ RateDiscountPolicy๋Š” TestConfig์—์„œ ํ•˜๋‚˜๋ฐ–์— ์—†๊ธฐ ๋•Œ๋ฌธ์— ์˜ค๋ฅ˜๊ฐ€ ๋œจ์ง€ ์•Š๊ณ  ๊ฒฐ๊ณผ๊ฐ€ ํ•˜๋‚˜๋กœ ์ž˜ ๋‚˜์˜ต๋‹ˆ๋‹ค.

 

์ด๋ฒˆ์—๋Š” ๋ถ€๋ชจ ํƒ€์ž…์œผ๋กœ ๋ชจ๋‘ ์กฐํšŒํ•˜๋Š” ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

@Test
    @DisplayName("๋ถ€๋ชจ ํƒ€์ž…์œผ๋กœ ๋ชจ๋‘ ์กฐํšŒ")
    void findAllBeanByParentType() {
        Map<String, DiscountPolicy> beansOfType = ac.getBeansOfType(DiscountPolicy.class);
        assertThat(beansOfType.size()).isEqualTo(2);
        for (String key : beansOfType.keySet()) {
            System.out.println("key = " + key + " value = " + beansOfType.get(key)); 
        }
    }

ํŠน์ • ํƒ€์ž…(๋ถ€๋ชจ ํƒ€์ž…)์„ ๋ชจ๋‘ ์กฐํšŒํ•˜๋Š” ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— beansOfType์„ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ , ์Šคํ”„๋ง์—์„œ getBeansOfType() ํ•จ์ˆ˜์˜ Returnํ˜•์„ Map์œผ๋กœ ๊ตฌํ˜„ํ•ด๋†จ๊ธฐ ๋•Œ๋ฌธ์— Map ํ•จ์ˆ˜๊ฐ€ ์‚ฌ์šฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๋˜, for (String key : beansOfType.keySet()) ์—ฌ๊ธฐ๋Š” beansOfType ๋ณ€์ˆ˜๊ฐ€ Map<String, DiscountPolicy>๋ผ๋Š” ํƒ€์ž…์ด์—ˆ๋Š”๋ฐ, ์—ฌ๊ธฐ์„œ keySet()์„ ํ•˜๋ฉด <String, DiscountPolicy>์—์„œ์˜ ์•ž ๋ฐ์ดํ„ฐ์ธ String ๋ฐ์ดํ„ฐ๋“ค๋งŒ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๋” ์‰ฝ๊ฒŒ ์„ค๋ช…ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

(์‚ฌ์‹ค 3-2์— ์žˆ๋Š” beansOfType์˜ Map ํ•จ์ˆ˜์™€ ๋‹ค๋ฅผ๊ฒŒ ์—†์Šต๋‹ˆ๋‹ค.)

beansOfType์ด๋ผ๋Š” ๋ณ€์ˆ˜๋Š” ์œ„์˜ ์‚ฌ์ง„๊ณผ ๊ฐ™์ด 2๊ฐœ์˜ ๊ฐ’์ด ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐ๊ฐ์˜ ํ•˜๋‚˜ ๊ฐ’์ด String, DiscountPolicy ํ˜•์˜ ๋ฐ์ดํ„ฐ 2๊ฐœ๋ฅผ ๊ฐ–๊ณ  ์žˆ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

.keySet์„ ํ•˜๋ฉด ์•ž์ชฝ์— ์žˆ๋Š” key ๊ฐ’๋“ค๋กœ๋งŒ ํ•ด์„œ ๋ฐฐ์—ด์„ ๋งŒ๋“ค์–ด์ค๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋ฉด for๋ฌธ์„ ํ†ตํ•ด ๋นˆ ์ด๋ฆ„์„ ํ•˜๋‚˜ํ•˜๋‚˜ ์ถœ๋ ฅํ•ด์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ , .size๋Š” ์‚ฌ์ง„์ฒ˜๋Ÿผ Map์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ช‡ ๊ฐœ๊ฐ€ ์žˆ๋‚˜ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

FixDiscountPolicy์™€ RateDiscountPolicy 2๊ฐœ๊ฐ€ ๋‚˜์™€์•ผ ํ•˜๊ธฐ์—,

2๊ฐœ๊ฐ€ ๋งž๊ฒŒ ๋‚˜์˜ค๋Š”์ง€ Assertions์˜ assertThat์œผ๋กœ ํ™•์ธํ•ด์ฃผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค,

 

๋ณธ๋ก ์œผ๋กœ ๋“ค์–ด๊ฐ€์„œ..

์ฐธ๊ณ ๋กœ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์—์„œ ์ถœ๋ ฅ๋ฌธ์€ ์‹ค๋ฌด์—์„œ ์‚ฌ์šฉ ์•ˆ ํ•ฉ๋‹ˆ๋‹ค.

๊ณต๋ถ€์šฉ์ด๋‹ˆ๊นŒ ๋ณด๊ธฐ ์‰ฝ๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด์—์š”.

 

ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋ถ€๋ชจ ํƒ€์ž…์œผ๋กœ ๋ชจ๋‘ ์กฐํšŒ

์ถœ๋ ฅ๋ฌธ ์ ์€ ๋ฐ๋กœ ๊ฒฐ๊ณผ๊ฐ€ ์•„์ฃผ ์ž˜ ๋‚˜์˜ต๋‹ˆ๋‹ค.

 

๋งˆ์ง€๋ง‰์œผ๋กœ, ์•„๊นŒ์ฒ˜๋Ÿผ ๋ถ€๋ชจ ํƒ€์ž…์œผ๋กœ ๋ชจ๋‘ ์กฐํšŒํ• ๊ฑด๋ฐ, Object ํƒ€์ž…์œผ๋กœ ๊บผ๋‚ด๋Š” ๊ฒƒ์„ ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

@Test
    @DisplayName("๋ถ€๋ชจ ํƒ€์ž…์œผ๋กœ ๋ชจ๋‘ ์กฐํšŒ - Object")
    void findAllBeanByObjectType() {
        Map<String, Object> beansOfType = ac.getBeansOfType(Object.class);
        for (String key : beansOfType.keySet()) {
            System.out.println("key = " + key + " value = " + beansOfType.get(key));
        }
    }

์ตœ์ƒ์œ„ ๊ฐ์ฒด์ธ Object์œผ๋กœ ์กฐํšŒํ•ด๋ณด์•˜์Šต๋‹ˆ๋‹ค.

์œ„์—๋ž‘ ๋น„์Šทํ•œ ๊ฒฝ์šฐ์ด๊ธฐ ๋•Œ๋ฌธ์—, beansOfType์„ ์‚ฌ์šฉํ–ˆ๊ตฌ์š”. ๊ทธ๋ ‡๊ธฐ์— Map ํƒ€์ž…์„ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

 

๋ฐ”๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋ถ€๋ชจ ํƒ€์ž…์œผ๋กœ ๋ชจ๋‘ ์กฐํšŒ - Object ์กฐํšŒ

์ด์•ผ.... ์—„์ฒญ ๋งŽ์ด ์ถœ๋ ฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ง€๊ธˆ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ฉด ๋ญ”๊ฐ€ ์Šคํ”„๋ง์ด ๋‚ด๋ถ€์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๋นˆ๋“ค๊นŒ์ง€ ๋‹ค ์ถœ๋ ฅ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์Šคํ”„๋ง ์•ˆ์—๋Š” ์—ฌ๋Ÿฌ ๋นˆ๋“ค์ด ๋“ฑ๋ก๋˜์–ด์žˆ๋Š”๋ฐ ์–˜๋„ค๋“ค๊นŒ์ง€ ๋‹ค ์ถœ๋ ฅ๋œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์™œ๋ƒํ•˜๋ฉด, ์ž๋ฐ” ๊ฐ์ฒด๋Š” ๋ชจ๋“  ๊ฒƒ์ด Object ํƒ€์ž…์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.


4. BeanFactory์™€ ApplicationContext

beanFactory์™€ ApplicationContext์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์ƒ์† ๊ด€๊ณ„

4-1. BeanFactory

  • ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์˜ ์ตœ์ƒ์œ„ ์ธํ„ฐํŽ˜์ด์Šค์ž…๋‹ˆ๋‹ค.
  • ์Šคํ”„๋ง ๋นˆ์„ ๊ด€๋ฆฌํ•˜๊ณ  ์กฐํšŒํ•˜๋Š” ์—ญํ• ์„ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค.
  • getBean()์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  • ์ง€๊ธˆ๊นŒ์ง€ ์šฐ๋ฆฌ๊ฐ€ ์‚ฌ์šฉํ–ˆ๋˜ ๋Œ€๋ถ€๋ถ„์˜ ๊ธฐ๋Šฅ์€ BeanFactory๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค.

 

4-2. ApplicationContext

  • BeanFactory ๊ธฐ๋Šฅ์„ ๋ชจ๋‘ ์ƒ์†๋ฐ›์•„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  • ๋นˆ์„ ๊ด€๋ฆฌํ•˜๊ณ  ๊ฒ€์ƒ‰ํ•˜๋Š” ๊ธฐ๋Šฅ์„ BeanFactory๊ฐ€ ์ œ๊ณตํ•ด์ฃผ๋Š”๋ฐ, ๊ทธ๋Ÿฌ๋ฉด ๋‘˜์˜ ์ฐจ์ด๊ฐ€ ๋ญ˜๊นŒ์š”?
  • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ฐœ๋ฐœํ•  ๋•Œ๋Š” ๋นˆ์„ ๊ด€๋ฆฌํ•˜๊ณ  ์กฐํšŒํ•˜๋Š” ๊ธฐ๋Šฅ์€ ๋ชฐ๋ก ์ด๊ณ  ์ˆ˜ ๋งŽ์€ ๋ถ€๊ฐ€ ๊ธฐ๋Šฅ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

 

<ApplicationContext๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๋ถ€๊ฐ€ ๊ธฐ๋Šฅ>

  • ์ธํ„ฐํŽ˜์ด์Šค ๋ถ„๋ฆฌ ์›์น™ ๊ธฐ์–ต!! ์ธํ„ฐํŽ˜์ด์Šค๋Š” ๋‹ค์–‘ํ•˜๊ฒŒ ๋ถ„๋ฆฌ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๋ฉ”์‹œ์ง€ ์†Œ์Šค๋ฅผ ํ™œ์šฉํ•œ ๊ตญ์ œํ™” ๊ธฐ๋Šฅ
    • ex) ํ•œ๊ตญ์—์„œ ๋“ค์–ด์˜ค๋ฉด ํ•œ๊ตญ์–ด๋กœ, ์˜์–ด๊ถŒ์—์„œ ๋“ค์–ด์˜ค๋ฉด ์˜์–ด๋กœ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค. (๊ตญ์ œํ™” ๊ธฐ๋Šฅ - ํŒŒ์ผ์„ ์—ฌ๋Ÿฌ ๊ฐœ๋กœ ๋ถ„๋ฆฌํ•ด ๋†“์Œ)
  • ํ™˜๊ฒฝ ๋ณ€์ˆ˜
    • ๋กœ์ปฌ, ๊ฐœ๋ฐœ, ์šด์˜ ๋“ฑ์„ ๊ตฌ๋ถ„ํ•ด์„œ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
  • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ด๋ฒคํŠธ
    • ์ด๋ฒคํŠธ๋ฅผ ๋ฐœํ–‰ํ•˜๊ณ  ๊ตฌ๋…ํ•˜๋Š” ๋ชจ๋ธ์„ ํŽธ๋ฆฌํ•˜๊ฒŒ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.
  • ํŽธ๋ฆฌํ•œ ๋ฆฌ์†Œ์Šค ์กฐํšŒ
    • ํŒŒ์ผ, ํด๋ž˜์Šค ํŒจ์Šค, ์™ธ๋ถ€ ๋“ฑ์—์„œ ๋ฆฌ์†Œ์Šค๋ฅผ ํŽธ๋ฆฌํ•˜๊ฒŒ ์กฐํšŒํ•ฉ๋‹ˆ๋‹ค.
<์ •๋ฆฌโœ๏ธ>

- ApplicationContext๋Š” BeanFactory์˜ ๊ธฐ๋Šฅ์„ ์ƒ์†๋ฐ›์Šต๋‹ˆ๋‹ค.
- ApplicationContext๋Š” ๋นˆ ๊ด€๋ฆฌ ๊ธฐ๋Šฅ + ํŽธ๋ฆฌํ•œ ๋ถ€๊ฐ€ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
- BeanFactory๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•  ์ผ์€ ๊ฑฐ์˜ ์—†์Šต๋‹ˆ๋‹คโœ”๏ธ. ๋ถ€๊ฐ€ ๊ธฐ๋Šฅ์ด ํฌํ•จ๋œ ApplicationContext๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
- BeanFactory๋‚˜ ApplicationContext๋ฅผ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

5. ๋‹ค์–‘ํ•œ ์„ค์ • ํ˜•์‹ ์ง€์› - ์ž๋ฐ” ์ฝ”๋“œ, XML

๊นŠ์ด๋Š” ์ดํ•ด ์•ˆ ํ•ด๋„ ๋˜๊ณ , ๊ทธ๋ƒฅ ์ด๋Ÿฐ๊ฒŒ ์žˆ๊ตฌ๋‚˜.. ์ •๋„๋กœ๋งŒ ์•Œ์•„๋‘๋ฉด ๋ฉ๋‹ˆ๋‹ค.

์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋Š” ๋‹ค์–‘ํ•œ ํ˜•์‹์˜ ์„ค์ • ์ •๋ณด๋ฅผ ๋ฐ›์•„๋“œ๋ฆด ์ˆ˜ ์žˆ๊ฒŒ ์œ ์—ฐํ•˜๊ฒŒ ์„ค๊ณ„๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

์ž๋ฐ” ์ฝ”๋“œ, XML, Groovy ๋“ฑ๋“ฑ ๋ง์ด์ฃ .

BeanFactory ์ธํ„ฐํŽ˜์ด์Šค ๋ฐ‘์— ApplicationContext ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

๋˜, ApplicationContext ์ธํ„ฐํŽ˜์ด์Šค ๋ฐ‘์—๋Š” AnnotationConfigApplicationContext, GenericXmlApplicationContext ๋“ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

AnnotationConfigApplicationContext๋Š” ์• ๋…ธํ…Œ์ด์…˜ ์„ค์ • ์ •๋ณด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ApplicationContext๋ฅผ ๋œปํ•˜๋ฉฐ, AppConfig.class๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

GenericXmlApplicationContext๋Š” ์ž๋ฐ” ์ฝ”๋“œ๊ฐ€ ์•„๋‹Œ XML์ด๋ผ๋Š” ๋ฌธ์„œ๋ฅผ ์„ค์ • ์ •๋ณด๋กœ ์‚ฌ์šฉํ•˜๋Š” ApplicationContext๋ฅผ ๋œปํ•˜๋ฉฐ, appConfig.xml์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ , ์ž„์˜๋กœ ๊ตฌํ˜„ํ•ด์„œ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. (XxxApplicationContext -> appConfig.xxx)

 

์š”์ฆ˜ ์ฃผ๋กœ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ์ž๋ฐ” ์ฝ”๋“œ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋Š” AnnotationConfigApplicationContext์ด๊ณ , ๊ณผ๊ฑฐ์— ๋งŽ์ด ์‚ฌ์šฉํ–ˆ๋˜ ๊ฒƒ์€ XML์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ–ˆ๋˜ GenericXmlApplicationContext์ž…๋‹ˆ๋‹ค.

XML์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋Š” GenericXmlApplicationContext๊ฐ€ ์˜›๋‚ ์— ๋งŽ์ด ์‚ฌ์šฉํ–ˆ๋˜ ๊ฒƒ์ด๋ผ ํ•ด๋„ ์ด๊ฒŒ ์–ด๋–ป๊ฒŒ ๋Œ์•„๊ฐ€๋Š”๊ตฌ๋‚˜.. ์ •๋„๋Š” ์•Œ์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

5-1. ์• ๋…ธํ…Œ์ด์…˜ ๊ธฐ๋ฐ˜ ์ž๋ฐ” ์ฝ”๋“œ ์„ค์ • ์‚ฌ์šฉ

์ง€๊ธˆ๊นŒ์ง€ ํ–ˆ๋˜ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ , new๋ฅผ ํ•ด์„œ AnnotationConfigApplicationContext๋ฅผ ๋งŒ๋“ค๋ฉด์„œ, AppConfig.class๋ผ๋Š” ์„ค์ • ์ •๋ณด๋ฅผ ๋„ฃ์–ด์คฌ์Šต๋‹ˆ๋‹ค.

=> new AnnotationConfigApplicationContext(AppConfig.class)

์ฆ‰, AnnotationConfigApplicationContext ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด์„œ ์ž๋ฐ” ์ฝ”๋“œ๋กœ ๋œ ์„ค์ • ์ •๋ณด๋ฅผ ๋„˜๊ธฐ๋ฉด ๋œ๋‹ค๋Š” ๋œป์ž…๋‹ˆ๋‹ค.

 

5-2. XML ์„ค์ • ์‚ฌ์šฉ

์ตœ๊ทผ์—๋Š” ์Šคํ”„๋ง ๋ถ€ํŠธ๋ฅผ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋ฉด์„œ XML ๊ธฐ๋ฐ˜์˜ ์„ค์ •์€ ์ž˜ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜, ์•„์ง ๋งŽ์€ ๋ ˆ๊ฑฐ์‹œ ํ”„๋กœ์ ํŠธ๋“ค์ด XML๋กœ ๋˜์–ด ์žˆ๊ณ , ๋˜ XML์„ ์‚ฌ์šฉํ•˜๋ฉด ์ปดํŒŒ์ผ ์—†์ด ๋นˆ ์„ค์ • ์ •๋ณด๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋Š” ์žฅ์ ๋„ ์žˆ์œผ๋ฏ€๋กœ ํ•œ ๋ฒˆ์ฏค ๋ฐฐ์›Œ๋ณด๋Š” ๊ฒƒ๋„ ๊ดœ์ฐฎ์€ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

GenericXmlApplicationContext๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด์„œ xml ์„ค์ • ํŒŒ์ผ์„ ๋„˜๊ธฐ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

 

ํ•œ ๋ฒˆ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

test ํŒจํ‚ค์ง€์˜ hello.core์— xml์ด๋ž€ ํŒจํ‚ค์ง€๋ฅผ ์šฐ์„  ๋งŒ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ , ์ด ํŒจํ‚ค์ง€ ์•ˆ์— XmlAppContext ๋ผ๋Š” ์ž๋ฐ” ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

public class XmlAppContext {
    
    @Test
    void xmlAppContext() {
        ApplicationContext ac = new GenericXmlApplicationContext("appConfig.xml");
        MemberService memberService = ac.getBean("memberService", MemberService.class);
        assertThat(memberService).isInstanceOf(MemberService.class);
    }
}

์šฐ์„  test ํด๋ž˜์Šค๋ถ€ํ„ฐ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.

์œ„์—์„œ ํ–ˆ๋˜ ๊ฑฐ๋ž‘ ๋น„์Šทํ•œ๋ฐ GenericXmlApplicationContext๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค๋Š” ์ ์ด ๋‹ค๋ฅด๋„ค์š”.

 

์ด๋Œ€๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ๋Œ๋ฆฌ๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋– ์„œ AppConfig๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

test ํŒจํ‚ค์ง€๊ฐ€ ์•„๋‹Œ src ํŒจํ‚ค์ง€์˜ main ํŒจํ‚ค์ง€์˜ resources ํŒจํ‚ค์ง€ ์•ˆ์— (XML ๊ตฌ์„ฑ ํŒŒ์ผ->Spring ๊ตฌ์„ฑ ์„ ํƒ)ํ•ด์„œ appConfig.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.xsd">

๋งŒ๋“ค๋ฉด ์ด๋ ‡๊ฒŒ ์žˆ๋Š”๋ฐ์š”. ์—ฌ๊ธฐ ๋ฐ‘์—๋‹ค๊ฐ€ ๋งˆ์ € ์ž‘์„ฑํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

<?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.xsd">

	//์—ฌ๊ธฐ์„œ๋ถ€ํ„ฐ ์ถ”๊ฐ€ํ•œ ๋ถ€๋ถ„
    <bean id="memberService" class="hello.core.member.MemberServiceImpl" >
        <constructor-arg name="memberRepository" ref="memberRepository" />
    </bean>

    <bean id="memberRepository" class="hello.core.member.MemoryMemberRepository"/>
</beans>

ํšŒ์›์ชฝ(memberService์™€ memberRepository) ๋นˆ์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.

class๋Š” ๊ฒฝ๋กœ๋ฅผ ๋‹ค ์ ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

์ฃผ๋ฌธ์ชฝ ๋นˆ์„ ์ถ”๊ฐ€ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

<bean id="orderService" class="hello.core.order.OrderServiceImpl" >
        <constructor-arg name="memberRepository" ref="memberRepository"/>
        <constructor-arg name="discountPolicy" ref="discountPolicy" />
    </bean>

    <bean id="discountPolicy" class="hello.core.discount.RateDiscountPolicy" />

์ด๋ ‡๊ฒŒ ์ฝ”๋“œ๋ฅผ ๋‹ค ์งœ๋†“์œผ๋ฉด test์—์„œ GenericXmlApplicationContext๊ฐ€ appConfig.xml์— ์ถ”๊ฐ€ํ•œ ๋‚ด์šฉ์„ ๋Œ์–ด๋‹ค๊ฐ€ ๋™์ž‘ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

ํ…Œ์ŠคํŠธ ์„ฑ๊ณตํ–ˆ์Šต๋‹ˆ๋‹ค.

<์ •๋ฆฌโœ๏ธ>

- xml ๊ธฐ๋ฐ˜์˜ appConfig.xml ์Šคํ”„๋ง ์„ค์ • ์ •๋ณด์™€ ์ž๋ฐ” ์ฝ”๋“œ๋กœ ๋œ AppConfig.java ์„ค์ • ์ •๋ณด๋ฅผ ๋น„๊ตํ•ด๋ณด๋ฉด ๊ฑฐ์˜ ๋น„์Šทํ•˜๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
- xml ๊ธฐ๋ฐ˜์œผ๋กœ ์„ค์ •ํ•˜๋Š” ๊ฒƒ์€ ์ตœ๊ทผ์— ์ž˜ ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ์ด ์ •๋„๋กœ ๋งˆ๋ฌด๋ฆฌ ํ•˜๊ณ , ํ•„์š”ํ•˜๋ฉด ์Šคํ”„๋ง ๊ณต์‹ ๋ ˆํผ๋Ÿฐ์Šค ๋ฌธ์„œ๋ฅผ ํ™•์ธํ•ด๋ณด๋ฉด ๋ฉ๋‹ˆ๋‹ค.
https://spring.io/projects/spring-framework

6. ์Šคํ”„๋ง ๋นˆ ์„ค์ • ๋ฉ”ํƒ€ ์ •๋ณด - BeanDefinition

์Šคํ”„๋ง์€ ์–ด๋–ป๊ฒŒ ์ด๋Ÿฐ ๋‹ค์–‘ํ•œ ์„ค์ • ํ˜•์‹์„ ์ง€์›ํ•˜๋Š” ๊ฒƒ์ผ๊นŒ์š”?

๊ทธ ์ค‘์‹ฌ์—๋Š” BeanDefinition์ด๋ผ๋Š” ์ถ”์ƒํ™”๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

 

์‰ฝ๊ฒŒ ์–˜๊ธฐํ•ด์„œ ์—ญํ• ๊ณผ ๊ตฌํ˜„์„ ๊ฐœ๋…์ ์œผ๋กœ ๋‚˜๋ˆˆ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

XML์„ ์ฝ์–ด์„œ BeanDefinition์„ ๋งŒ๋“ค๋ฉด ๋˜๊ณ , ์ž๋ฐ” ์ฝ”๋“œ๋ฅผ ์ฝ์–ด์„œ BeanDefinition์„ ๋งŒ๋“ค๋ฉด ๋ฉ๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ , ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ ์ž…์žฅ์—์„œ๋Š” ์ž๋ฐ” ์ฝ”๋“œ์ธ์ง€, XML์ธ์ง€ ๋ชฐ๋ผ๋„ ๋ฉ๋‹ˆ๋‹ค. ์˜ค์ง BeanDefinition๋งŒ ์•Œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๋นˆ์„ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

์ด BeanDefinition์„ ๋นˆ ์„ค์ • ๋ฉ”ํƒ€ ์ •๋ณด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

@Bean, <bean> ํ•˜๋‚˜๋‹น ๊ฐ๊ฐ ํ•˜๋‚˜์”ฉ ๋ฉ”ํƒ€ ์ •๋ณด๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋Š” ์ด ๋ฉ”ํƒ€ ์ •๋ณด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์Šคํ”„๋ง ๋นˆ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ ์ž์ฒด๋Š” BeanDefinition์—๋งŒ ์˜์กดํ•ฉ๋‹ˆ๋‹ค.

์–˜๊ฐ€ class๋กœ ์„ค์ •๋œ ์ •๋ณด์ธ์ง€, xml๋กœ ์„ค์ •๋œ ์ •๋ณด์ธ์ง€, ์ž„์˜๋กœ ์„ค์ •๋œ ์ •๋ณด์ธ์ง€ ์ƒ๊ด€์„ ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ฒฐ๊ตญ ๋ณด๋ฉด BeanDefinition ์ž์ฒด๊ฐ€ ์ธํ„ฐํŽ˜์ด์Šค์ž…๋‹ˆ๋‹ค.

 

์ฝ”๋“œ ๋ ˆ๋ฒจ๋กœ ์กฐ๊ธˆ ๋” ๊นŠ์ด ์žˆ๊ฒŒ ๋“ค์–ด๊ฐ€๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์ด๊ฑฐ ๊ทธ๋ฆผ์€ ๊ฑ ๊นŠ์ด ์žˆ๊ฒŒ ์•Œ๋ฉด ์ข‹์€๊ฑฐ๊ณ , ๋ชฐ๋ผ๋„ ๋ฉ๋‹ˆ๋‹ค.

๋ชฐ๋ผ๋„ ์Šคํ”„๋ง ๊ฐœ๋ฐœํ•˜๋Š” ๋ฐ์— ์ „ํ˜€ ์ง€์žฅ ์—†์Šต๋‹ˆ๋‹ค.

AnnotationConfigApplicationContext๋Š” AnnotatedBeanDefinitionReader๋ฅผ ์‚ฌ์šฉํ•ด์„œ AppConfig.class๋ฅผ ์ฝ๊ณ  BeanDefinition์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

GenericXmlApplicationContext๋Š” XmlBeanDefinitionReader๋ฅผ ์‚ฌ์šฉํ•ด์„œ appConfig.xml ์„ค์ • ์ •๋ณด๋ฅผ ์ฝ๊ณ , BeanDefinition์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ, ์ƒˆ๋กœ์šด ํ˜•์‹์˜ ์„ค์ • ์ •๋ณด๊ฐ€ ์ถ”๊ฐ€ ๋˜๋ฉด, XxxBeanDefinitionReader๋ฅผ ๋งŒ๋“ค์–ด์„œ BeanDefinition์„ ์ƒ์„ฑํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

 

6-1. BeanDefinition ์‚ดํŽด๋ณด๊ธฐ

<BeanDefinition ์ •๋ณดโญ>

- BeanClassName: ์ƒ์„ฑํ•  ๋นˆ์˜ ํด๋ž˜์Šค ๋ช… (์ž๋ฐ” ์„ค์ •์ฒ˜๋Ÿผ factory ์—ญํ• ์˜ ๋นˆ์„ ์‚ฌ์šฉํ•˜๋ฉด ์—†์Œ)
- factoryBeanName: factory ์—ญํ• ์˜ ๋นˆ์„ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ์˜ ์ด๋ฆ„ (ex - appConfig)
- factoryMethodName: ๋นˆ์„ ์ƒ์„ฑํ•  factory ๋ฉ”์„œ๋“œ ์ง€์ • (ex - memberService)
- Scope: ์‹ฑ๊ธ€ํ†ค (๊ธฐ๋ณธ๊ฐ’)
- lazyInit: ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ƒ์„ฑํ•  ๋•Œ, ๋นˆ์„ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ ์‹ค์ œ ๋นˆ์„ ์‚ฌ์šฉํ•  ๋•Œ๊นŒ์ง€ ์ตœ๋Œ€ํ•œ ์ƒ์„ฑ์„ ์ง€์—ฐ์ฒ˜๋ฆฌ ํ•˜๋Š”์ง€์˜ ์—ฌ๋ถ€
- InitMethodName: ๋นˆ์„ ์ƒ์„ฑํ•˜๊ณ , ์˜์กด ๊ด€๊ณ„๋ฅผ ์ ์šฉํ•œ ๋’ค์— ํ˜ธ์ถœ๋˜๋Š” ์ดˆ๊ธฐํ™” ๋ฉ”์„œ๋“œ ์ด๋ฆ„
- DestoryMethodName: ๋นˆ์˜ ์ƒ๋ช… ์ฃผ๊ธฐ๊ฐ€ ๋๋‚˜์„œ ์ œ๊ฑฐํ•˜๊ธฐ ์ง์ „์— ํ˜ธ์ถœ๋˜๋Š” ๋ฉ”์„œ๋“œ ์ด๋ฆ„
- Constructor arguments, Properties: ์˜์กด ๊ด€๊ณ„ ์ฃผ์ž…์—์„œ ์‚ฌ์šฉ (์ž๋ฐ” ์„ค์ •์ฒ˜๋Ÿผ factory ์—ญํ• ์˜ ๋นˆ์„ ์‚ฌ์šฉํ•˜๋ฉด ์—†์Œ)

์ด๊ฒŒ ๊ทผ๋ฐ ๋ง๋กœ๋งŒ ๋ณด๋ฉด ์ดํ•ด๊ฐ€ ์ž˜ ์•ˆ ๊ฐˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ, ์ฝ”๋“œ๋กœ ํ•œ ๋ฒˆ ๋” ๋ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

test ํŒจํ‚ค์ง€์˜ hello.core์—์„œ beandefinition์ด๋ผ๋Š” ํŒจํ‚ค์ง€๋ฅผ ๋งŒ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ , ์ด ํŒจํ‚ค์ง€ ์•ˆ์— BeanDefinitionTest๋ผ๋Š” ์ž๋ฐ” ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋นˆ ์„ค์ • ๋ฉ”ํƒ€์ •๋ณด๋ฅผ ํ™•์ธํ•˜๋Š” ํ…Œ์ŠคํŠธ ์ž…๋‹ˆ๋‹ค.

public class BeanDefinitionTest {

    AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
    
    @Test
    @DisplayName("๋นˆ ์„ค์ • ๋ฉ”ํƒ€์ •๋ณด ํ™•์ธ")
    void findApplicationBean() {
        String[] beanDefinitionNames = ac.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            BeanDefinition beanDefinition = ac.getBeanDefinition(beanDefinitionName);

            if (beanDefinition.getRole() == BeanDefinition.ROLE_APPLICATION) {
                System.out.println("beanDefinitionName = " + beanDefinitionName +
                        " beanDefinition = " + beanDefinition);
            }
        }
    }
}

 

ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋นˆ ์„ค์ • ๋ฉ”ํƒ€์ •๋ณด ํ™•์ธ

์ด ๊ฒฐ๊ณผ์—์„œ memberService์™€ memberRepository๋ฅผ ๋ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์†์„ฑ์„ ์ซ™ ๋ด๋ณด๋ฉด scope๋ผ๋Š” ๊ฒŒ ์žˆ๋Š”๋ฐ ์—ฌ๊ธฐ์„  ํ• ๋‹น์ด ๋˜์–ด์žˆ์ง€ ์•Š๋„ค์š”. (ํ• ๋‹น์ด ๋˜์–ด์žˆ์ง€ ์•Š์œผ๋ฉด ์‹ฑ๊ธ€ํ†ค์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.)

abstract๋Š” ์ถ”์ƒ, lazyInit์€ ์Šคํ”„๋ง ๋นˆ์„ ์‹ค์ œ ์‚ฌ์šฉํ•  ์‹œ์ ์— ์ดˆ๊ธฐํ™”ํ•˜๋ผ๋Š” ์ •๋ณด์ž…๋‹ˆ๋‹ค.

์ด ์™ธ์—๋„ ๋‹ค์–‘ํ•œ ์ •๋ณด๊ฐ€ ์žˆ์œผ๋ฉด ์œ„์— ์žˆ๋Š” ์ •๋ณด๋“ค ์ฐธ๊ณ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

๊ทธ๋ƒฅ ์ง€๊ธˆ์€ ์ด๋Ÿฐ ์ข…๋ฅ˜์˜ ๋ฉ”ํƒ€ ์ •๋ณด๊ฐ€ ์žˆ๋‹ค ์ •๋„๋กœ ์•Œ์•„๋‘๋ฉด ๋˜๊ณ , ์ด๋Ÿฐ ๋ฉ”ํƒ€ ์ •๋ณด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์‹ค์ œ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์•„๋‘๋ฉด ๋ฉ๋‹ˆ๋‹ค.

<์ •๋ฆฌโœ๏ธ>

- BeanDefinition์„ ์ง์ ‘ ์ƒ์„ฑํ•ด์„œ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์— ๋“ฑ๋กํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
=> ํ•˜์ง€๋งŒ, ์‹ค๋ฌด์—์„œ BeanDefinition์„ ์ง์ ‘ ์ •์˜ํ•˜๊ฑฐ๋‚˜ ์‚ฌ์šฉํ•  ์ผ์€ ๊ฑฐ์˜ ์—†์Šต๋‹ˆ๋‹ค.
- BeanDefinition์— ๋Œ€ํ•ด์„œ๋Š” ๋„ˆ๋ฌด ๊นŠ์ด ์ดํ•ดํ•˜๊ธฐ ๋ณด๋‹ค๋Š” ์Šคํ”„๋ง์ด ๋‹ค์–‘ํ•œ ํ˜•ํƒœ์˜ ์„ค์ • ์ •๋ณด๋ฅผ BeanDefinition์œผ๋กœ ์ถ”์ƒํ™”ํ•ด์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ ์ •๋„๋งŒ ์ดํ•ดํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.
- ๊ฐ€๋” ์Šคํ”„๋ง ์ฝ”๋“œ๋‚˜ ์Šคํ”„๋ง ๊ด€๋ จ ์˜คํ”ˆ ์†Œ์Šค์˜ ์ฝ”๋“œ๋ฅผ ๋ณผ ๋•Œ, BeanDefinition์ด๋ผ๋Š” ๊ฒƒ์ด ๋ณด์ผ ๋•Œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
  ์ด ๋•Œ, ์ด๋Ÿฐ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ๋– ์˜ฌ๋ฆฌ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

์˜ค๋Š˜ ๊ณต๋ถ€๋„ ์ด๋ ‡๊ฒŒ ๋์ด ๋‚ฌ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ์—๋Š” ์‹ฑ๊ธ€ํ†ค์— ๊ด€ํ•ด์„œ ๊ณต๋ถ€ํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.

๊ทธ๋Ÿผ ์•ˆ๋‡ฝ!