2021. 10. 10. 08:00ใBack-End ์์ ์ค/Spring Framework
๐ ๋ชฉ์ฐจ
01. [Spring] ์คํ๋ง ํต์ฌ ์๋ฆฌ
02. [Spring] ์ข์ ๊ฐ์ฒด ์งํฅ ์ค๊ณ์ 5๊ฐ์ง ์์น (SOLID)
03. [Spring] ๊ฐ์ฒด ์งํฅ ์ค๊ณ์ ์คํ๋ง
04. [Spring] OCP์ DIP ๊ณ ๋ คํ๊ธฐ
05. [Spring] ๊ฐ์ฒด ์งํฅ ์๋ฆฌ ์ ์ฉ - ์๋ก์ด ํ ์ธ ์ ์ฑ
๊ฐ๋ฐ
06. [Spring] AppConfig ๋ฆฌํฉํฐ๋ง
07. [Spring] Ioc, DI Container
08. [Spring] ์คํ๋ง ์ปจํ
์ด๋ ์์ฑ
09. [Spring] ์ฑ๊ธํค ์ปจํ
์ด๋
10. [Spring] Component Scan And Auto wired Start
11. [Spring] ์์กด๊ด๊ณ ์ฃผ์
๋ฐฉ๋ฒ
12. [Spring] Bean Life Cycle Call Back
13. [Spring] Bean Scope
๐ ๋น ์ค์ฝํ
์คํ๋ง ๋น์ด ์คํ๋ง ์ปจํ ์ด๋์ ์์๊ณผ ํจ๊ป ์์ฑ๋์ด ์คํ๋ง ์ปจํ ์ด๋๊ฐ ์ข ๋ฃ๋ ๋๊น์ง ์ ์ง๋๋ ๊ฒ์ด์์.
์ด๊ฒ์ ์คํ๋ง ๋น์ด ๊ธฐ๋ณธ์ ์ผ๋ก ์ฑ๊ธํค ์ค์ฝํ๋ก ์์ฑ๋์๊ธฐ ๋๋ฌธ์ธ๋ฐ, ์ค์ฝํ๋ ๋น์ด ์กด์ฌํ ์ ์๋ ๋ฒ์๋ฅผ ๋ปํ๋ ๊ฒ์ด์์.
๐ ์คํ๋ง์ ์ง์ ์ค์ฝํ
- ์ฑ๊ธํค : ๊ธฐ๋ณธ ์ค์ฝํ, ์คํ๋ง ์ปจํ ์ด๋์ ์์๊ณผ ์ข ๋ฃ๋ ๋๊น์ง ์ ์ง๋๋ ๊ฐ์ฅ ๋์ ๋ฒ์์ ์ค์ฝํ
- ํ๋กํ ํ์
: ์คํ๋ง ์ปจํ
์ด๋๋ ํ๋กํ ํ์
๋น์ ์์ฑ๊ณผ ์์กด ๊ด๊ณ ์ฃผ์
๊น์ง๋ง ๊ด์ฌํ๊ณ , ๋ ์ด์ ๊ด์ฌํ์ง ์๋๋ค.
์ฆ, ์์ฑ์ ํ๊ณ , ์์ฒญ์์๊ฒ ์๋ต์ผ๋ก ๋์ ธ์ฃผ๊ธฐ๋ง ํ๊ณ , ์ ๊ฒฝ์ฐ์ง ์๋๋ค. - ์น ๊ด๋ จ ์ค์ฝํ :
- request : Web ์์ฒญ์ด ๋ค์ด์ค๊ณ , ์๋ต์ผ๋ก ๋๊ฐ ๋๊น์ง ์ ์ง๋๋ ์ค์ฝํ
- session : Web Session์ด ์์ฑ๋๊ณ , ์ข ๋ฃ๋ ๋ ๊น์ง ์ ์ง๋๋ ์ค์ฝํ
- application : Web Sevlet Context์ ๊ฐ์ ๋ฒ์๋ก ์ ์ง๋๋ ์ค์ฝํ
๋น ์ค์ฝํ๋ ๋ค์๊ณผ ๊ฐ์ด ์ง์ ํ ์ ์๋ ๊ฒ์ด์์.


๐ Prototype Scope
์ฑ๊ธํค ์ค์ฝํ์ ๋น์ ์กฐํํ๋ฉด ์คํ๋ง ์ปจํ ์ด๋๋ ํญ์ ๊ฐ์ ์ธ์คํด์ค์ ์คํ๋ง ๋น์ ๋ฐํํ๋ ๊ฒ์ด์์. ๋ฐ๋ฉด ํ๋กํ ํ์ ์ค์ฝํ๋ ์คํ๋ง ์ปจํ ์ด๋์ ์กฐํํ๋ฉด ์คํ๋ง ์ปจํ ์ด๋๋ ํญ์ ์๋ก์ด ์ธ์คํด์ค๋ฅผ ์์ฑํด์ ๋ฐํํ๋ ๊ฒ์ด์์.
๐ ์ฑ๊ธํค ๋น ์์ฒญ

๋จผ์ ์ฑ๊ธํค ์ค์ฝํ์ ๋น์ ์คํ๋ง ์ปจํ ์ด๋์ ์์ฒญ์ ํ๋ฉด ์คํ๋ง ์ปจํ ์ด๋๋ ์์ ์ด ๊ด๋ฆฌํ๋ ์คํ๋ง ๋น์ ๋ฐํํ๋ ๊ฒ์ด์์. ๊ทธ๋ฐ ๋ค ์คํ๋ง ์ปจํ ์ด๋์ ๊ฐ์ ์์ฒญ์ด ์๋ ๊ฐ์ ๊ฐ์ฒด ์ธ์คํด์ค๋ฅผ ๋ฐํ ํ๋ต๋๋ค!
๐ ํ๋กํ ํ์ ๋น ์์ฒญ 1

์ต์ด ํ๋กํ ํ์ ์ค์ฝํ์ ๋น์ ์คํ๋ง ์ปจํ ์ด๋์ ์์ฒญํ๋ฉด ์คํ๋ง ์ปจํ ์ด๋๋ ๊ทธ ์์ ์ ํ๋กํ ํ์ ๋น์ ๋ง๋ค๊ณ , ํ์ํ ์์กด ๊ด๊ณ๋ฅผ ์ฃผ์ ํ๋ ๊ฒ์ด์์.
๐ ํ๋กํ ํ์ ๋น ์์ฒญ 2

์คํ๋ง ์ปจํ ์ด๋๊ฐ ์์ฑํ ํ๋กํ ํ์ ๋น์ ํด๋ผ์ด์ธํธ์๊ฒ ๋ฐํํ๋ฉด ์คํ๋ง ์ปจํ ์ด๋์ ๊ฐ์ ์์ฒญ์ด ์์ ๋, ํญ์ ์๋ก์ด ํ๋กํ ํ์ ๋น์ ๋ง๋ค์ด์ ๋ฐํํ๋ ๊ฒ์ด์์.
๋ง์น ์ฑ๊ธํค ์ค์ฝํ๋ ์ด๋ค ์๋ฐ ์ ์์ ์๋ ์ผ๊ตด์ ์ ๊ธฐ์ตํ๋ ์ฃผ์ธ๋ถ๊ป์ ์๋์ด ์ค์๋ฉด "์ด๋จธ! ๋ ์ค์ จ๋ค์! 401ํธ๋ก ์ค๋น ํด ๋์์ต๋๋ค!"๋ผ๊ณ ํ๋ ๊ฒ๊ณผ ๊ฐ์๋ฐ, ํ๋กํ ํ์ ์ ๊ฒฝ์ฐ ์ฃผ์ธ๋ถ๊ป์ ์๋ฉด์ธ์ ์ฅ์ ๊ฐ ์์ผ์ ๊ฐ์ง๊ตฌ 1๋ ๋ด๋ด ์ค๋๋๋ "์ด์์ค์ธ์! ์ฒ์ ๋ต๊ฒ ์ต๋๋ค!" ํ๋ฉด์ ๋ค๋ฅธ ๋ฐฉ์ ์ฃผ๋ ๊ฒ์ด ์ฐ์๋๋ ๊ฒ์ด์์.
์ ๋ฆฌํ์๋ฉด
์ฌ๊ธฐ์ ํต์ฌ์ ์คํ๋ง ์ปจํ ์ด๋๋ ํ๋กํ ํ์ ๋น์ ์์ฑํ๊ณ , ์์กด ๊ด๊ณ ์ฃผ์ , ์ด๊ธฐํ๊น์ง๋ง ์ฒ๋ฆฌํ๋ค๋ ๊ฒ์ด์์.
ํด๋ผ์ด์ธํธ์ ๋น์ ๋ฐํํ๊ณ , ๊ทธ ๋ค์ ์คํ๋ง ์ปจํ ์ด๋๋ ์์ฑ๋ ํ๋กํ ํ์ ๋น์ ๊ด๋ฆฌํ์ง ์๋ ๊ฒ์ด์์.ํ๋กํ ํ์ ๋น์ ๊ด๋ฆฌํ ์ฑ ์์ ํ๋กํ ํ์ ๋น์ ๋ฐ์ ํด๋ผ์ด์ธํธ์๊ฒ ์๊ธฐ ๋๋ฌธ์ [ @PreDestroy ] ๊ฐ์ ์ข ๋ฃ Method๊ฐ ํธ์ถ๋์ง ์๋ ๊ฒ์ด์์.
๐ ์ฑ๊ธํค ์ค์ฝํ ๋น ํ ์คํธ

์ฑ๊ธํค ์ค์ฝํ์ ๋น์ ์กฐํํ๋ singletonBeanFind()๋ฅผ ์คํํ๋ฉด ๊ฒฐ๊ณผ๋ ์๋์ ๊ฐ์ ๊ฒ์ด์์.

- Bean ์ด๊ธฐํ Method ํธ์ถ(์คํ)
- ๊ฐ์ ์ธ์คํด์ค์ Bean ์กฐํ
- ์ข ๋ฃ Method ์ ์ ํธ์ถ


ํ๋กํ ํ์ ์ค์ฝํ์ ๋น์ ์กฐํํ๋ prototypeBeanFind()๋ฅผ ๋ถ๋ฌ๋ณผ๊ฒ์!

- ์ฑ๊ธํค ๋น์ ์คํ๋ง ์ปจํ ์ด๋ ์์ฑ ์์ ์ ์ด๊ธฐํ Method๊ฐ ์คํ ๋์ง๋ง, ํ๋กํ ํ์ ์ค์ฝํ์ ๋น์ ์คํ๋ง ์ปจํ ์ด๋์์ ๋น์ ์กฐํํ ๋ ์์ฑ๋๊ณ , ์ด๊ธฐํ Method ์คํ
- ํ๋กํ ํ์ ๋น์ 2๋ฒ ์กฐํํ๊ธฐ ๋๋ฌธ์ ์์ ํ ๋ค๋ฅธ ์คํ๋ง ๋น์ด ๋ง๋ค์ด์ง๊ณ , ์ด๊ธฐํ๋ 2๋ฒ ์คํ
- ์ฑ๊ธํค ๋น์ ์คํ๋ง ์ปจํ ์ด๋๊ฐ ๊ด๋ฆฌํ๊ธฐ ๋๋ฌธ์ ์คํ๋ง ์ปจํ ์ด๋๊ฐ ์ข ๋ฃ๋ ๋, ๋น์ ์ข ๋ฃ Method๊ฐ ์คํ๋๋, ํ๋กํ ํ์ ๋น์ ์คํ๋ง ์ปจํ ์ด๋๊ฐ ์์ฑ๊ณผ ์์กด ๊ด๊ณ ์ฃผ์ ๊ทธ๋ฆฌ๊ณ , ์ด๊ธฐํ ๊น์ง๋ง ์ ๊ฒฝ์ฐ๊ณ , ์ ๊ฒฝ์ ๊บผ ๋ฒ๋ฆฌ๊ธฐ ๋๋ฌธ์ ์ฆ, ๋ ๊ด๋ฆฌํ์ง ์๊ธฐ ๋๋ฌธ์ ํ๋กํ ํ์ ๋น์ ์คํ๋ง ์ปจํ ์ด๋๊ฐ ์ข ๋ฃ๋ ๋ [ @PreDestory ] ๊ฐ์ ์ข ๋ฃ Method๊ฐ ์ ํ ์คํ๋์ง ์๋๋ค.
๐ Prototype Scope - Singleton Bean๊ณผ ํจ๊ป ์ฌ์ฉ์ ๋ฌธ์ ์
์คํ๋ง ์ปจํ ์ด๋์ ํ๋กํ ํ์ ์ค์ฝํ์ ๋น์ ์์ฒญํ๋ฉด ํญ์ ์๋ก์ด ๊ฐ์ฒด ์ธ์คํด์ค๋ฅผ ์์ฑํด์ ๋ฐํํ๋ ๊ฒ์ด์์.
ํ์ง๋ง, ์ฑ๊ธํค ๋น๊ณผ ํจ๊ป ์ฌ์ฉํ ๋ ์๋ํ๋๋ก ๋์ํ์ง ์๋ ๊ฒ์ด์์.
๐ Spring Container Prototype Bean Direct Request 1

์ต์ด ํด๋ผ์ด์ธํธ A๋ ์คํ๋ง ์ปจํ ์ด๋์ ํ๋กํ ํ์ ๋น์ ์์ฒญํ๊ณ , ์คํ๋ง ์ปจํ ์ด๋๋ ํ๋กํ ํ์ ๋น์ ์๋ก ์์ฑํ ๋ค ๋ฐํ(x01)ํ๋ ๊ฒ์ด์์. ํด๋น ๋น์ count Field ๊ฐ์ 0์ธ ์ํ์ธ ๊ฒ์ด์์.
ํด๋ผ์ด์ธํธ๋ ์กฐํํ ํ๋กํ ํ์ ๋น์ addCount()๋ฅผ ๋ถ๋ฅด๋ฉด์ count Field๋ฅผ +1ํ๋ ๊ฒ์ด์์.
๊ทธ๋ ๊ฒ ๋๋ฉด ํ๋กํ ํ์ ๋น(x01)์ count๋ 1์ด ๋๊ฒ ์ง์?


๐ Singleton Bean at use Prototype Bean 1

clientBean์ ์ฑ๊ธํค์ด๊ธฐ ๋๋ฌธ์ ๋ณดํต ์คํ๋ง ์ปจํ ์ด๋ ์์ฑ ์์ ์ ํจ๊ป ์์ฑ๋๊ณ , ์์กด ๊ด๊ณ ์ฃผ์ ๋ ์ด ๋ ๋ฐ์ํ๋ ๊ฒ์ด์์.
clientBean์ ์์กด ๊ด๊ณ ์๋ ์ฃผ์ ์ ์ฌ์ฉํ๊ณ , ์ฃผ์ ์์ ์ ์คํ๋ง ์ปจํ ์ด๋์ ํ๋กํ ํ์ ๋น์ ์์ฒญํ๋ ๊ฒ์ด์์.
์คํ๋ง ์ปจํ ์ด๋๋ ํ๋กํ ํ์ ๋น์ ์์ฑํ ๋ค clientBean์ ๋ฐํ์ ํ๊ณ , ํ๋กํ ํ์ ๋น์ count Field ๊ฐ์ 0์ธ ๊ฒ์ด์์.
๊ทธ๋ฐ ๋ค clientBean์ ํ๋กํ ํ์ ๋น์ ๋ด๋ถ Field์ ์ฐธ์กฐ๊ฐ์ ๋ณด๊ดํ๋ต๋๋ค.
๐ Singleton Bean at use Prototype Bean 2

ํด๋ผ์ด์ธํธ A๋ clientBean์ ์คํ๋ง ์ปจํ ์ด๋์ ์์ฒญํด์ ๋ฐ๋ ๊ฒ์ด์์. ์ฑ๊ธํค์ด๊ธฐ ๋๋ฌธ์ ๋น์ฐํ ํญ์ ๊ฐ์ clientBean์ด ๋ฐํ๋ ๊ฒ์ด์์.
ํด๋ผ์ด์ธํธ A๊ฐ clientBean.logic()์ ๋ถ๋ฅด๊ฒ ๋๋ฉด clientBean์ prototypeBean์ addCount()๋ฅผ ๋ถ๋ฌ ํ๋กํ ํ์ ๋น์ count๋ฅผ ์ฆ๊ฐ์ํค๊ฒ ๋๊ณ , ์ด ๋๋ฌธ์ count ๊ฐ์ด 1์ด ๋๋ ๊ฒ์ด์์.
๐ Singleton Bean at use Prototype Bean 3

ํด๋ผ์ด์ธํธ B๊ฐ clientBean์ ์คํ๋ง ์ปจํ ์ด๋์ ์์ฒญํด์ ๋ฐ์ ๋, clientBean์ ์ฑ๊ธํค์ด๊ธฐ ๋๋ฌธ์ ํญ์ ๊ฐ์ clientBean์ด ๋ฐํ๋๋ ๊ฒ์ด์์.
์ฌ๊ธฐ์ ์ค์ํ ๊ฒ์ clientBean์ด ๋ด๋ถ์ ๊ฐ์ง๊ณ ์๋ ํ๋กํ ํ์
๋น์ ์ด๋ฏธ ๊ณผ๊ฑฐ์ ์ฃผ์
์ด ๋๋ ๋น์ธ ๊ฒ์ด์์.
์ฃผ์
์์ ์ ์คํ๋ง ์ปจํ
์ด๋์ ์์ฒญํด์ ํ๋กํ ํ์
๋น์ด ์๋ก ์์ฑ๋ ๊ฒ์ด์ง ์ฌ์ฉํ ๋๋ง๋ค ์๋ก ์์ฑ๋๋ ๊ฒ์ด ์๋ ๊ฒ์ด์์!
ํด๋ผ์ด์ธํธ B๋ clientBean.logic()์ ๋ถ๋ฅด๊ฒ ๋๊ณ , clientBean์ prototypeBean์ addCount()๋ฅผ ๋ถ๋ฌ ํ๋กํ ํ์ ๋น์ count๋ฅผ ์ฆ๊ฐ์ํค๊ฒ ๋๋ ๊ฒ์ด์์. ์๋ count ๊ฐ์ด 1์ด์๊ธฐ ๋๋ฌธ์ 2๊ฐ ๋๋ ๊ฒ์ด์์.



์คํ๋ง์ ์ผ๋ฐ์ ์ผ๋ก ์ฑ๊ธํค ๋น์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ์ฑ๊ธํค ๋น์ด ํ๋กํ ํ์
๋น์ ์ฌ์ฉํ๊ฒ ๋๋ ๊ฒ์ด์์.
๊ทธ๋ฐ๋ฐ, ์ฑ๊ธํค ๋น์ ์์ฑ ์์ ์๋ง ์์กด ๊ด๊ณ ์ฃผ์
์ ๋ฐ๊ธฐ ๋๋ฌธ์ ํ๋กํ ํ์
๋น์ด ์๋ก ์์ฑ๋๊ธฐ๋ ํ๋, ์ฑ๊ธํค ๋น๊ณผ ํจ๊ป ๊ณ์ ์ ์ง๋๋ ๊ฒ์ด ๋ฌธ์ ์ธ ๊ฒ์ด์์.
์๋ง ํ๋กํ ํ์
์ ์ฌ์ฉํ๋ค๋ ๊ฒ์ ์ด๊ฒ์ ํฌ๋งํ๊ณ ์ฌ์ฉํ๋ ๊ฒ์ ์๋๊ฒ์ด์์.
ํ๋กํ ํ์
๋น์ ์ฃผ์
์์ ์๋ง ์๋ก ์์ฑํ๋๊ฒ ์๋๋ผ, ์ฌ์ฉํ ๋ ๋ง๋ค ์๋ก ์์ฑํด์ ์ฌ์ฉํ๋ ๊ฒ์ ์ํ๊ธฐ ๋๋ฌธ์ ์ด๊ฒ์ ์ฌ์ฉํ๋ ค๊ณ ํ๋ ๊ฒ์ผํ
๋๊น์!
๐ก ์ฐธ๊ณ :
์ฌ๋ฌ ๋น์์ ๊ฐ์ ํ๋กํ ํ์ ๋น์ ์ฃผ์ ๋ฐ์ผ๋ฉด ์ฃผ์ ๋ฐ๋ ์์ ์ ๊ฐ๊ฐ ์๋ก์ด ํ๋กํ ํ์ ๋น ์์ฑ.
์ ๋ค์ด clientA, clientB๊ฐ ๊ฐ๊ฐ ์์กด๊ด๊ณ ์ฃผ์ ์ ๋ฐ๊ฒ ๋๋ฉด ๊ฐ๊ฐ ๋ค๋ฅธ ์ธ์คํด์ค์ ํ๋กํ ํ์ ๋น ์ฃผ์ ์ ๋ฐ๋๋ค.
clientA ๐ prototypeBean@x01
clientB ๐ prototypeBean@x02
๋จ, ์ฌ์ฉํ ๋ ๋ง๋ค ์๋ก ์์ฑ๋๋ ๊ฒ์ ์๋
๐ Prototype Scope - Singleton Bean๊ณผ ํจ๊ป ์ฌ์ฉ์ Provider๋ก ๋ฌธ์ ํด๊ฒฐ
์ฑ๊ธํค ๋น๊ณผ ํ๋กํ ํ์ ๋น์ ํจ๊ป ์ฌ์ฉํ ๋, ์ด๋ป๊ฒ ํ๋ฉด ์์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ์ฌ ์๋ก์ด ํ๋กํ ํ์ ๋น์ ๋ง๋ค ์ ์์๊น์?
๐ Spring Container Request
๊ฐ์ฅ ๊ฐ๋จํ ๋ฐฉ๋ฒ์ ์ฑ๊ธํค ๋น์ด ํ๋กํ ํ์ ์ ์ฌ์ฉํ ๋ ๋ง๋ค ์คํ๋ง ์ปจํ ์ด๋์ ์๋ก ์์ฒญํ๋ ๊ฒ์ด์์.

ac.getBean()์ ํตํด ์๋ก์ด ํ๋กํ ํ์ ๋น์ด ์์ฑ๋๋ ๊ฒ์ ๋ณผ ์ ์๋ ๊ฒ์ด์์.
์์กด ๊ด๊ณ๋ฅผ ์ธ๋ถ์์ ์ฃผ์ (DI) ๋ฐ๋ ๊ฒ์ด ์๋๊ณ , ์ด๋ ๊ฒ ์ง์ ํ์ํ ์์กด ๊ด๊ณ๋ฅผ ์ฐพ๋ ๊ฒ์ Dependency Lookup(DL)์ด๋ผ๊ณ ํ๋ฉฐ, ์ด๋ ์์กด ๊ด๊ณ ์กฐํ(ํ์)์ด๋ผ ํ๋ ๊ฒ์ด์์.
์คํ๋ง ์ ํ๋ฆฌ์ผ์ด์ ์ปจํ ์คํธ ์ ์ฒด๋ฅผ ์ฃผ์ ๋ฐ๊ฒ ๋๋ฉด ์คํ๋ง ์ปจํ ์ด๋์ ์ข ์์ ์ธ ์ฝ๋๊ฐ ๋๊ณ , ๋จ์ ํ ์คํธ ์ญ์ ์ด๋ ค์ด ๊ฒ์ด์์.
์ด ์์ ์ ํ์ํ ๊ธฐ๋ฅ์ ์ง์ ํ ํ๋กํ ํ์ ๋น์ ์ปจํ ์ด๋์์ ๋์ ์ฐพ์์ฃผ๋ DL ์ ๋์ ๊ธฐ๋ฅ๋ง ์์ผ๋ฉด ๋๋ ๊ฒ์ด์์.
์ด๊ฒ์ ์คํ๋ง์ ์ ์ ํ๊ฒ ์ง์ํด ์ค๋ต๋๋ค!
๐ ObjectFactory, ObjectProvider
์ง์ ํ ๋น์ ์ปจํ
์ด๋์์ ๋์ ์ฐพ์์ฃผ๋ DL ์๋น์ค๋ฅผ ์ ๊ณตํ๋ ๊ฒ์ด ๋ฐ๋ก ObjectProvider์ธ ๊ฒ์ด์์.
์ฐธ๊ณ ๋ก ๊ณผ๊ฑฐ์๋ ObjectFactory๊ฐ ์์๋๋ฐ, ์ฌ๊ธฐ์ ํธ์ ๊ธฐ๋ฅ์ ์ถ๊ฐํด์ ObjectProvider๊ฐ ๋ง๋ค์ด์ง ๊ฒ์ด์์.

์์ ์ฝ๋๋ฅผ ์คํํด๋ณด๋ฉด prototypeBeanProvider.getObject()๋ฅผ ํตํด ํญ์ ์๋ก์ด ํ๋กํ ํ์ ๋น์ด ์์ฑ๋๋ ๊ฒ์ด์์.
ObjectProvicer์ getObjet()๋ฅผ ๋ถ๋ฅด๊ฒ ๋๋ฉด ๋ด๋ถ์์ ์คํ๋ง ์ปจํ ์ด๋๋ฅผ ํตํด ํด๋น ๋น์ ์ฐพ์ ๋ฐํํ๋ ๊ฒ์ด์์. (DL)
์คํ๋ง์ด ์ ๊ณตํ๋ ๊ธฐ๋ฅ์ ์ฌ์ฉํ์ง๋ง, ๊ธฐ๋ฅ์ด ๋จ์ํ๊ธฐ ๋๋ฌธ์ ๋จ์ ํ ์คํธ๋ฅผ ๋ง๋ค๊ฑฐ๋, mock ์ฝ๋๋ฅผ ๋ง๋ค๊ธฐ๋ ํจ์ฌ ์ฝ๋ต๋๋ค!
ObjectProvider๋ ์ง๊ธ ๋ฑ ํ์ํ DL ์ ๋์ ๊ธฐ๋ฅ๋ง ์ ๊ณตํ๋ ๊ฒ์ด์์.
ํน์ง
- ObjectFactory : ๊ธฐ๋ฅ์ด ๋จ์, ๋ณ๋ Library์์, Spring์ ์์กด
- ObjectProvider : ObjectFactory ์์, Option, Stream ์ฒ๋ฆฌ ๋ฑ ํธ์ ๊ธฐ๋ฅ์ด ๋ง๊ณ , ๋ณ๋ Library ํ์ ์์ผ๋ฉฐ, Spring์ ์์กด
๐ JSR-330 Provider
๋ง์ง๋ง์ผ๋ก ์ฌ์ฉํ ์ ์๋ ๋ฐฉ๋ฒ์ javax.inject.Provider๋ผ๋ JSR-330 Java Stadard๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด์์.
์ด๊ฒ์ ์ฌ์ฉํ๊ธฐ ์ํด์๋ java.inject:javax.inject:1 Library๋ฅผ gradle์ ์ถ๊ฐ ํด์ค์ผ ํ๋ต๋๋ค!
package javax.inject;
public interface Provider<T> {
T get();
}
/* -------------------------------------------- */
//implementation 'javax.inject:javax.inject:1' gradle ์ถ๊ฐ ํ์
@Autowired private Provider<PrototypeBean> provider;
public int logic() {
PrototypeBean prototypeBean = provider.get();
prototypeBean.addCount();
int count = prototypeBean.getCount();
return count;
}
์์ ์ฝ๋๋ฅผ ์คํํด๋ณด๋ฉด provider.get()์ ํตํด ํญ์ ์๋ก์ด ํ๋กํ ํ์ ๋น์ ์์ฑํ๋ ๊ฒ์ด์์.
provider์ get()์ ๋ถ๋ฅด๊ฒ ๋๋ฉด ๋ด๋ถ์์ ์คํ๋ง ์ปจํ ์ด๋๋ฅผ ํตํด ํด๋น ๋น์ ์ฐพ์ ๋ฐํํ๋ต๋๋ค! (DL)
JAVA Standard์ด๋ฉฐ, ๊ธฐ๋ฅ์ด ๋จ์ํ๋ฏ๋ก, ๋จ์ ํ ์คํธ๋ฅผ ๋ง๋ค๊ฑฐ๋, mock ์ฝ๋๋ฅผ ๋ง๋ค๊ธฐ๋ ํจ์ฌ ์ฌ์์ง๋ ๊ฒ์ด์์.
Provider๋ ๋ฑ ํ์ํ DL ์ ๋ณด์ ๊ธฐ๋ฅ๋ง ์ ๊ณตํ๋ ๊ฒ์ด์์.
ํน์ง
- get() ํ๋๋ก ๊ธฐ๋ฅ์ด ๋งค์ฐ ๋จ์
- ๋ณ๋ Library ํ์
- JAVA Standard๋ก Spring์ด ์๋ ๋ค๋ฅธ ์ปจํ ์ด๋์์๋ ์ฌ์ฉ ๊ฐ๋ฅ
์ ๋ฆฌํ์๋ฉด
ํ๋กํ ํ์ ๋น์ ๊ทธ๋ฌ๋ฉด ์ธ์ ์ฌ์ฉํ ๊น์? ๋งค๋ฒ ์ฌ์ฉํ ๋ ๋ง๋ค ์์กด ๊ด๊ณ ์ฃผ์ ์ด ์๋ฃ๋ ์๋ก์ด ๊ฐ์ฒด๊ฐ ํ์ํ๋ฉด ์ฌ์ฉํ๋ฉด ๋๋ ๊ฒ์ด์์. ๊ทธ๋ฐ๋ฐ, ์ค๋ฌด์์๋ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฐ๋ฐํด๋ณด๋ฉด, ์ฑ๊ธํค ๋น์ผ๋ก ๋๋ถ๋ถ์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๊ธฐ ๋๋ฌธ์ ์ด๊ฒ์ ์ฐ๋ ์ผ์ ๋๋ฌผ๋ค๊ณ ํฉ๋๋ค!
ObjectProvider, JSR330 Provider ๋ฑ์ ํ๋กํ ํ์ ๋ฟ ์๋๋ผ DL์ด ํ์ํ ๊ฒฝ์ฐ ์ธ์ ๋ ์ฌ์ฉ ๊ฐ๋ฅํ ๊ฒ์ด์์.
๐ก ์ฐธ๊ณ :
์คํ๋ง์ด ์ ๊ณตํ๋ Method์ @Lookup์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ๋ ์์ผ๋, ์ด์ ๋ฐฉ๋ฒ๋ค๋ก ์ถฉ๋ถํ๋ค.
์๋ฐ ํ์ค์ธ JSR-330 Provider๋ฅผ ์ฌ์ฉํ ๊ฒ์ธ์ง ์๋๋ฉด ์คํ๋ง์ด ์ ๊ณตํ๋ ObjectProvider๋ฅผ ์ฌ์ฉํ ๊ฒ์ธ์ง ๊ณ ๋ฏผ์ด ๋๋ ์๊ฐ์ด ์จ๋ค๋ฉด ObjcetProvider๋ DL์ ์ํ ํธ์ ๊ธฐ๋ฅ์ ๋ง์ด ์ ๊ณตํ๋ฉฐ, ์คํ๋ง ์ธ์ ๋ณ๋ ์์กด ๊ด๊ณ์ถ๊ฐ๊ฐ ํ์ ์๊ธฐ ๋๋ฌธ์ ํธํ๋ค. ๊ฑฐ์ ๊ทธ๋ด์ผ์ ์๊ฒ ๋ค๋ง ์ฝ๋๋ฅผ ์คํ๋ง์ด ์๋ ๋ค๋ฅธ ์ปจํ ์ด๋์์๋ ์ฌ์ฉํ ์ ์์ด์ผ ํ๋ค๋ฉด JSR-330 Provider๋ฅผ ์ฌ์ฉํด์ผ ํ๋ค.
์คํ๋ง์ ์ฌ์ฉํ๋ค ๋ณด๋ฉด ์ด ๊ธฐ๋ฅ ๋ฟ ์๋๋ผ, ๋ค๋ฅธ ๊ธฐ๋ฅ๋ค๋ JAVA Standard์ ์คํ๋ง์ด ์ ๊ณตํ๋ ๊ธฐ๋ฅ์ด ๊ฒน์น ๋๊ฐ ๋ง์๋ฐ, ๋๋ถ๋ถ ์คํ๋ง์ด ๋ ๋ค์ํ๊ณ , ํธ๋ฆฌํ ๊ธฐ๋ฅ์ ์ ๊ณตํ๊ธฐ ๋๋ฌธ์ ํน๋ณํ ๋ค๋ฅธ ์ปจํ ์ด๋๋ฅผ ํจ๊ป ์ฌ์ฉํ์ง ์๋ ์ด์ ์คํ๋ง์ด ์ ๊ณตํ๋ ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ค.
๐ Web Scope
์ง๊ธ๊น์ง ์ฑ๊ธํค๊ณผ ํ๋กํ ํ์ ์ ๋ํด ์์๋ณธ ๊ฒ์ด์์. ์ฑ๊ธํค์ ์คํ๋ง ์ปจํ ์ด๋์ ์์๊ณผ ๋๊น์ง ํจ๊ปํ๋ ๋ฒ์๊ฐ ๋งค์ฐ ํฐ ์ค์ฝํ์ด๊ณ , ํ๋กํ ํ์ ์ ์์ฑ๊ณผ ์์กด๊ด๊ณ ์ฃผ์ , ๊ทธ๋ฆฌ๊ณ ์ด๊ธฐํ๊น์ง๋ง ์งํํ๋ ํน๋ณํ ์น๊ตฌ์ธ ๊ฒ์ด์์.
์น ์ค์ฝํ์ ํน์ง
- ์น ์ค์ฝํ๋ ์น ํ๊ฒฝ์์๋ง ๋์
- ์น ์ค์ฝํ๋ ํ๋กํ ํ์
๊ณผ ๋ค๋ฅด๊ฒ ์คํ๋ง์ด ํด๋น ์ค์ฝํ์ ์ข
๋ฃ ์์ ๊น์ง ๊ด๋ฆฌ.
๋ฐ๋ผ์ ์ข ๋ฃ Method๊ฐ ํธ์ถ
์น ์ค์ฝํ ์ข ๋ฅ
- request : HTTP ์์ฒญ ํ๋๊ฐ ๋ค์ด์ค๊ณ , ์๋ต์ผ๋ก ๋๊ฐ ๋ ๊น์ง ์ ์ง๋๋ ์ค์ฝํ๋ก ๊ฐ๊ฐ์ HTTP ์์ฒญ๋ง๋ค ๋ณ๋์ Bean ์ธ์คํด์ค๊ฐ ์์ฑ, ๊ด๋ฆฌ
- session : HTTP Session๊ณผ ๋์ผํ ์๋ช ์ฃผ๊ธฐ๋ฅผ ๊ฐ์
- application : Servlet Context์ ๋์ผํ ์๋ช ์ฃผ๊ธฐ๋ฅผ ๊ฐ์
- websocket : ์น ์์ผ๊ณผ ๋์ผํ ์๋ช ์ฃผ๊ธฐ๋ฅผ ๊ฐ์
๐ HTTP Requset ๋น ๊ฐ๊ฐ ํ ๋น๋๋ Request Scope

๐ Make Request Scope Example
WEB Environment Insert
์น ์ค์ฝํ๋ ์น ํ๊ฒฝ์์๋ง ๋์ํ๊ธฐ ๋๋ฌธ์ WEB ํ๊ฒฝ์ด ๋์ํ๋๋ก Library ์ถ๊ฐ ํ์
build.gradle

main Method ์คํ ์ ์๋์ ๊ฐ์ด ๊ฒฐ๊ณผ๊ฐ ๋์ค๋ฉด ์ฑ๊ณตํ ๊ฒ์ด์์.

Spring-boot-starter-web Library๋ฅผ ์ถ๊ฐํ๋ฉด ์คํ๋ง ๋ถํธ๋ ๋ด์ฅ ํฐ์ผ ์๋ฒ๋ฅผ ํ์ฉํ์ฌ ์น ์๋ฒ์ ์คํ๋ง์ ํจ๊ป ์คํํ๋ ๊ฒ์ด์์.
์คํ๋ง ๋ถํธ๋ ์น ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์์ผ๋ฉด ์ง๊ธ๊น์ง ๊ณต๋ถํ๋ AnnotationConfigApplicationContext๋ฅผ ๊ธฐ๋ฐ์ผ๋ก Application์ ๊ตฌ๋ํ์ง๋ง, ์น ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์ถ๊ฐ๋๋ฉด ์น์ ๊ด๋ จ๋ ์ถ๊ฐ ์ค์ ๊ณผ ํ๊ฒฝ์ด ํ์ํ๊ธฐ ๋๋ฌธ์ AnnotationConfigServletWebServerApplicationContext๋ฅผ ๊ธฐ๋ฐ์ผ๋ก Application์ ๊ตฌ๋ํ๋ ๊ฒ์ด์์.
๋ง์ฝ ๊ธฐ๋ณธ Port์ธ 8080์ด ๋ค๋ฅธ ๊ณณ์์ ์ฌ์ฉํ์ฌ ๊ธฐ๋์ด ๋์ง ์๋๋ค๋ฉด 9090 ๋ฑ๊ณผ ๊ฐ์ด ๋ณ๊ฒฝํ๋ฉด ๋๋ ๊ฒ์ด์์.
main/resources/application.properties

๐ Request Scope Example Develop
๋์์ ์ฌ๋ฌ HTTP Request๊ฐ ์ค๋ฉด ์ ํํ ์ด๋ค Request๊ฐ ๋จ๊ธด Log์ธ์ง ๊ตฌ๋ถํ๊ธฐ ์ด๋ ค์ด ๊ฒ์ด์์.
์ด๋ด ๋ ์ฌ์ฉํ๊ธฐ ์ข์๊ฒ์ด ๋ฐ๋ก Request Scope์ธ ๊ฒ์ด์์.
์ฐ๋ฆฌ๊ฐ ๋ง๋ค์ด๋ณผ Code์ ๊ฒฐ๊ณผ๋ ๋ค์๊ณผ ๊ฐ์์!
[d06b992f...] request scope bean create[d06b992f...][http://localhost:8080/log-demo] controller test
[d06b992f...][http://localhost:8080/log-demo] service id = testId
[d06b992f...] request scope bean close
- Common Format : [UUID] {requestURL} {message}
- UUID๋ฅผ ์ฌ์ฉํ์ฌ HTTP ์์ฒญ ๊ตฌ๋ถ
- requestURL ์ ๋ณด๋ ์ถ๊ฐํ์ฌ ์ด๋ค URL Request์์ ๋จ์ Log์ธ์ง ํ์ธ

์์ Class๋ Log๋ฅผ ์ถ๋ ฅํ๊ธฐ ์ํ JunyHarangLogger์ธ ๊ฒ์ด์์.
@Scope(value = "request")๋ฅผ ํตํด request ์ค์ฝํ๋ฅผ ์ง์ ํ ๊ฒ์ด์์. ์ด์ Bean์ HTTP Request ๋น ํ๋์ฉ ์์ฑ๋๊ณ , HTTP Request๊ฐ ๋๋๋ ์์ ์ ์๋ฉธ๋๋ ๊ฒ์ด์์.
ํด๋น Bean์ด ์์ฑ๋๋ ์์ ์ ์๋์ผ๋ก @PostConstruct ์ด๊ธฐํ Method๋ฅผ ์ฌ์ฉํ์ฌ uuid๋ฅผ ์์ฑํ๊ณ ์ ์ฅํ๋ ๊ฒ์ด์์. ํด๋น Bean์ HTTP Request ๋น ํ๋์ฉ ์์ฑ๋๊ธฐ ๋๋ฌธ์ uuid๋ฅผ ์ ์ฅํด๋๋ฉด ๋ค๋ฅธ HTTP Request์ ๊ตฌ๋ถ์ด ๊ฐ๋ฅํ๋ต๋๋ค!
ํด๋น Bean์ด ์๋ฉธ๋๋ ์์ ์ @PreDestroy๋ฅผ ์ฌ์ฉํด์ ์ข ๋ฃ ๋ฉ์์ง๋ฅผ ๋จ๊ธธ ๊ฒ์ด์์.
requestURL์ ํด๋น Bean์ด ์์ฑ๋๋ ์์ ์๋ ์ ์ ์๊ธฐ ๋๋ฌธ์ ์ธ๋ถ์์ setter๋ก ์ ๋ ฅ ๋ฐ๊ฒ ํ ๊ฒ์ด์์.

์์ Controller๋ Logger๊ฐ ์ ๋์ํ๋์ง ํ์ธํ๊ธฐ ์ํ Test์ฉ Controller์ธ ๊ฒ์ด์์.
์ฌ๊ธฐ์ HttpServletRequest๋ฅผ ํตํด ์์ฒญ URL์ ๋ฐ์๊ตฌ์. (requestURL Value = http://localhost:8080/log-demo)
์ด๋ ๊ฒ ๋ฐ์ requestURL ๊ฐ์ JunyHarangLogger์ ์ ์ฅํด๋๋ ๊ฒ์ด์์. JunyHarangLogger๋ HTTP ์์ฒญ ๋น ๊ฐ๊ฐ ๊ตฌ๋ถ๋๊ธฐ ๋๋ฌธ์ ๋ค๋ฅธ HTTP ์์ฒญ ๋๋ฌธ์ ๊ฐ์ด ์์ด์ง ์๋ ๊ฒ์ด์์.
์ปจํธ๋กค๋ฌ์์ ์ด๊ฒ์ ์ปจํธ๋กค๋ฌ ์ ๋ค๋ค!๋ผ๋ ๋ก๊ทธ๋ฅผ ๋จ๊ธธ ๊ฒ์ด์์.
๐ก ์ฐธ๊ณ :
requestURL์ JunyHarangLogger์ ์ ์ฅํ๋ ๋ถ๋ถ์ ์ปจํธ๋กค๋ฌ ๋ณด๋ค ๊ณตํต ์ฒ๋ฆฌ๊ฐ ๊ฐ๋ฅํ ์คํ๋ง ์ธํฐ์ ํฐ๋ ์๋ธ๋ฆฟ ํํฐ ๊ฐ์ ๊ณณ์ ํ์ฉํ๋ ๊ฒ์ด ์ข๋ค.

๋น์ฆ๋์ค ๋ก์ง์ด ์๋ ์๋น์ค ๊ณ์ธต์์๋ ๋ก๊ทธ๋ฅผ ์ถ๋ ฅํ๊ฒ ํ ๊ฒ์ด์์.
์ฌ๊ธฐ์ ์ค์ํ ๊ฒ์ request scope๋ฅผ ์ฌ์ฉํ์ง ์๊ณ , ๋งค๊ฐ ๋ณ์(ํ๋ผ๋ฏธํฐ)๋ก ์ด ๋ชจ๋ ์ ๋ณด๋ฅผ ์๋น์ค ๊ณ์ธต์ ๋๊ธด๋ค๋ฉด ๋งค๊ฐ ๋ณ์๊ฐ ๋ง์ ๋๋ฌ์ ์ง๋ ๊ฒ์ด์์. ๋ ๋ฌธ์ ๋ requestURL ๊ฐ์ ์น๊ณผ ๊ด๋ จ๋ ์ ๋ณด๊ฐ ์น๊ฐ ๊ด๋ จ์๋ ์๋น์ค ๊ณ์ธต๊น์ง ๋์ด๊ฐ๊ฒ ๋๋ ๊ฒ์ด์์. ์น๊ณผ ๊ด๋ จ๋ ๋ถ๋ถ์ ์ปจํธ๋กค๋ฌ๊น์ง๋ง ์ฌ์ฉํ๋ ๊ฒ์ด ์ข๊ณ , ์๋น์ค ๊ณ์ธต์ ์น ๊ธฐ์ ์ ์ข ์๋์ง ์๊ณ , ๊ฐ๊ธ์ ์์ํ๊ฒ ์ ์งํ๋ ๊ฒ์ด ์ ์ง๋ณด์ ๊ด์ ์์ ์ข์ ๊ฒ์ด์์.
request scope์ JunyHarangLogger ๋๋ถ์ ์ด๋ฐ ๋ถ๋ถ์ ๋งค๊ฐ ๋ณ์๋ก ๋๊ธฐ๊ธฐ ์๊ณ , JunyHarangLogger์ ๋ฉค๋ฒ๋ณ์์ ์ ์ฅํ์ฌ ์ฝ๋์ ๊ณ์ธต์ ๊น๋ํ๊ฒ ์ ์งํ ์ ์๋ ๊ฒ์ด์์.
๊ธฐ๋ํ๋ ์ถ๋ ฅ

๊ธฐ๋์๋ ๋ค๋ฅธ Exception
Error creating bean with name 'junyHarangLogger': Scope 'request' is not active for the
current thread; consider defining a scoped proxy for this bean
if you intend to refer to it from a singleton;
Main Method๊ฐ ์๋ ์คํ๋ง ์ ํ๋ฆฌ์ผ์ด์ ์ ์คํ์ํค๋ฉด ์์ ๊ฐ์ด Exception์ด ํฐ์ง๋๋ฐ, ๋ฉ์์ง ๋ง์ง๋ง์ ์ฑ๊ธํค์ด๋ผ๋ ๋จ์ด๊ฐ ๋์ค๋ ๊ฒ์ด์์. ์คํ๋ง ์ ํ๋ฆฌ์ผ์ด์ ์ ์คํํ๋ ์์ ์ ์ฑ๊ธํค ๋น์ ์์ฑํด์ ์ฃผ์ ์ด ๊ฐ๋ฅํ๋, request ์ค์ฝํ ๋น์ ์์ง ์์ฑ๋์ง ์๋ ๊ฒ์ด์์. ํด๋น ๋น์ ์ค์ ํด๋ผ์ด์ธํธ์ ์์ฒญ์ด ์์ผ ์์ฑํ ์ ์๊ธฐ ๋๋ฌธ์ธ ๊ฒ์ด์์.
๐ Scope And Provider
์์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด์ ์ฒซ๋ฒ์งธ๋ก ์ฌ์ฉํด ๋ณผ ์ ์๋ ํด๊ฒฐ ๋ฐฉ์์ ๋ฐ๋ก Provider์ธ ๊ฒ์ด์์.
๊ฐ๋จํ ObjectProvider๋ฅผ ์ฌ์ฉํด ๋ณผ ๊ฒ์ด์์.
package hello.core.web;
import hello.core.common.MyLogger;
import hello.core.logdemo.LogDemoService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
@Controller @RequiredArgsConstructor
public class LogDemoController {
private final LogDemoService logDemoService;
private final ObjectProvider<JunyHarangLogger> jhLoggerProvider;
@RequestMapping("log-demo") @ResponseBody
public String logDemo(HttpServletRequest request) {
String requestURL = request.getRequestURL().toString();
JunyHarangLogger jhLogger = jhLoggerProvider.getObject();
jhLoggerProvider.setRequestURL(requestURL);
jhLoggerProvider.log("์ด๊ฒ์ ์ปจํธ๋กค๋ฌ ์
๋ค๋ค!");
logDemoService.logic("testId");
return "OK";
}
}
package hello.core.logdemo;
import hello.core.common.MyLogger;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.stereotype.Service;
@Service @RequiredArgsConstructor
public class LogDemoService {
private final ObjectProvider<JunyHarangLogger> jhLoggerProvider;
public void logic(String id) {
JunyHarangLogger jhLogger = jhLoggerProvider.getObject();
jhLogger.log("์๋น์ค์์ ๋์ด์จ ๋๋ฌด id๋ ๋ค์๊ณผ ๊ฐ์ต๋ค๋ค! \n" + id);
}
}
Main()์ ์คํํด์ WEB Browser์ [ http://localhost:8080/log-demo ] ๋ผ๊ณ ์ ๋ ฅํ๋ฉด ์๋์ ๊ฐ์ด ๊ฒฐ๊ณผ๊ฐ ๋์ฌ ๊ฒ์ด์์.

ObjectProvider ๋์ ObjectProvider.getObject()๋ฅผ ๋ถ๋ฌ๋ด๋ ์์ ๊น์ง request Scope Bean์ ์์ฑ์ ์ง์ฐํ ์ ์๋ ๊ฒ์ด์์.
ObjcetProvider.getObject()๋ฅผ ๋ถ๋ฌ๋ด๋ ์์ ์๋ HTTP ์์ฒญ์ด ์งํ์ค์ด๊ธฐ ๋๋ฌธ์ request Scope Bean์ ์์ฑ์ด ์ ์ ์ฒ๋ฆฌ ๋๋ต๋๋ค!
ObjcetProvider.getObject()๋ฅผ LogDemoController, Log DemoService์์ ๊ฐ๊ฐ ํ๋ฒ์ฉ ๋ฐ๋ก ํธ์ถํด๋ ๊ฐ์ HTTP ์์ฒญ์ด๋ฉด ๊ฐ์ Spring Bean์ด ๋ฐํ๋๋ ๊ฒ์ด์์. ์ด๊ฑธ ์ง์ ๊ตฌ๋ถํ๋ ค๋ฉด ์ ๋ง ํ๋ค ๊ฒ์ด์์.
๐ Scope And Proxy
์ด๋ฒ์๋ Proxy ๋ฐฉ์์ ์ฌ์ฉํด ๋ณผ๊ฒ์ด์์.
๐ก ์ฐธ๊ณ : Proxy๋?
์ฌ์ ์ ์๋ฏธ : 1) ๋๋ฆฌ(๊ถ)
2) ๋๋ฆฌ์ธ
3) (์ธก์ , ๊ณ์ฐํ๋ ค๋ ๋ค๋ฅธ ๊ฒ์ ๋ํํ๋๋ก ์ด์ฉํ๋) ๋์ฉ๋ฌผ
Proxy Server๋?
Client๊ฐ ์์ ์ ํตํด์ ๋ค๋ฅธ Network Svice์ ๊ฐ์ ์ ์ผ๋ก ์ ์ํ ์ ์๊ฒ ํด์ฃผ๋ ์ปดํจํฐ ์์คํ ์ด๋, ์์ฉ ํ๋ก๊ทธ๋จ. Server์ Client ์ฌ์ด์ ์ค๊ณ๊ธฐ๋ก์จ ๋๋ฆฌ๋ก ํต์ ์ ์ํํ๋ ๊ฒ์ ๊ฐ๋ฆฌ์ผ 'Proxy', ๊ทธ ์ค๊ณ ๊ธฐ๋ฅ์ ํ๋ ๊ฒ์ Proxy Server๋ผ๊ณ ์นญํ๋ค.
Spring Proxy๋?
์ ๋ ๊ฐ์ฒด๋ฅผ Proxy๋ก ๊ฐ์ธ๊ณ , Client ์ธก์ ์์ฒญ์ ๊ฐ์ธ์ง Proxy Class๋ฅผ ํตํด ๋๋ฆฌ๋ก ์ฒ๋ฆฌํ๋๋ก ์ ๋

proxyMode = ScopedProxyMode.TARGET_CLASS ์ด ๋ถ๋ถ์ด ์์ฃผ์์ฃผ ์ค์ํ ๊ฒ์ด์์.
์ด๊ฒ์ ์ ์ฉ ๋์์ด ์ธํฐํ์ด์ค๊ฐ ์๋ ํด๋์ค๋ฉด TARGET_CLASS๋ฅผ ์ฌ์ฉํ๊ณ , ์ธํฐํ์ด์ค๋ผ๋ฉด INTERFACES๋ฅผ ์ฐ๋ฉด ๋๋ ๊ฒ์ด์์.
์ด๋ ๊ฒ ํ๋ฉด JunyHarangLogger์ ๊ฐ์ง ํ๋ก์ ํด๋์ค๋ฅผ ๋ง๋ค๊ณ , HTTP request์ ์๊ด ์์ด ๊ฐ์ง ํ๋ก์ ํด๋์ค๋ฅผ ๋ค๋ฅธ Bean์ ๋ฏธ๋ฆฌ ์ฃผ์ ํ ์ ์๋ ๊ฒ์ด์์.


Code๋ฅผ ์ ๋ณด๊ฒ ๋๋ฉด LogDemoController์ LogDemoService๋ Provider ์ฌ์ฉ ์ ๊ณผ ์์ ๋์ผํ ๊ฒ์ด์์.
์ ๊ทธ๋ด๊น์??
๐ WEB Scope And Proxy Principle of motion
๋จผ์ ์ฃผ์ ๋ JunyHarangLogger๋ฅผ ํ์ธ ํด ๋ณผ๊ฒ์!

์์ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ ๊ฒ๊ณผ ๊ฐ์ด Spring์ด ๋ง๋ Proxy ๊ฐ์ฒด๊ฐ ๋ง๋ค์ด ์ง ๊ฒ์ด์์!
@Scop์ proxyMode = ScopedProxyMode.TARGET_CLASS๋ฅผ ์ค์ ํ๊ฒ ๋๋ฉด ์คํ๋ง ์ปจํ ์ด๋๋ CGLIB๋ผ๋ ๋ฐ์ดํธ ์ฝ๋๋ฅผ ์กฐ์ํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํด์, JunyHarangLogger๋ฅผ ์์ ๋ฐ๋ ๊ฐ์ง ํ๋ก์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ๊ฒ์ด์์.
๊ฒฐ๊ณผ๋ฅผ ํ์ธ ํด ๋ณด๋ฉด ๋ฑ๋กํ ์์ํ JunyHarangLogger ํด๋์ค๊ฐ ์๋๋ผ [ JunyHarangLogger$$EnhancerBySpringCGLIB ]๋ผ๋ ํด๋์ค๋ก ๋ง๋ค์ด์ง ๊ฐ์ฒด๊ฐ ๋์ ๋ฑ๋ก๋ ๊ฒ์ ๋ณผ ์ ์๋ ๊ฒ์ด์์. ๊ทธ๋ฆฌ๊ณ , ์คํ๋ง ์ปจํ ์ด๋์ [ jhLogger ] ๋ผ๋ ์ด๋ฆ์ผ๋ก ์ง์ง ๋์ ๊ฐ์ง ํ๋ก์ ๊ฐ์ฒด๋ฅผ ๋ฑ๋กํ๋ ๊ฒ์ด์์.
ac.getBean("jhLogger", JunyHarangLogger.class)๋ก ์กฐํํด๋ ํ๋ก์ ๊ฐ์ฒด๊ฐ ์กฐํ ๋๋ต๋๋ค! ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ์์กด ๊ด๊ณ ์ฃผ์ ๋ ์ด ๊ฐ์ง ํ๋ก์ ๊ฐ์ฒด๊ฐ ์ฃผ์ ๋๋ ๊ฒ์ด์์.

๊ฐ์ง ํ๋ก์ ๊ฐ์ฒด๋ ์์ฒญ์ด ์ค๋ฉด ๊ทธ ๋ ๋ด๋ถ์์ ์ง๋น ๋น์ ์์ฒญํ๋ ์์ ๋ก์ง์ด ๋ค์ด ์๋ ๊ฒ์ด์์.
๊ฐ์ง ํ๋ก์ ๊ฐ์ฒด๋ ๋ด๋ถ์ ์ง์ง jhLogger๋ฅผ ์ฐพ๋ ๋ฐฉ๋ฒ์ ์๊ณ ์๋ ๊ฒ์ด์์.
ํด๋ผ์ด์ธํธ๊ฐ jhLogger.logic()์ ๋ถ๋ฅด๊ฒ ๋๋ฉด ์ฌ์ค ๊ฐ์ง ํ๋ก์ ๊ฐ์ฒด์ ๋ฉ์๋๋ฅผ ํธ์ถํ ๊ฒ์ด์์.
๊ฐ์ง ํ๋ก์ ๊ฐ์ฒด๋ request ์ค์ฝํ์ ์ง์ง jhLogger.logic()์ ๋ถ๋ฅด๊ฒ ๋๋ ๊ฒ์ด์ง์.
๊ฐ์ง ํ๋ก์ ๊ฐ์ฒด๋ ์๋ณธ ํด๋์ค๋ฅผ ์์ ๋ฐ์ ๋ง๋ค์ด์ก๊ธฐ ๋๋ฌธ์ ์ด ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ๋ ํด๋ผ์ด์ธํธ ์ ์ฅ์์๋ ์ฌ์ค ์๋ณธ์ธ์ง ์๋์ง๋ ๋ชจ๋ฅด๊ฒ ๋์ผํ๊ฒ ์ฌ์ฉํ ์ ์๋ต๋๋ค! ๋๋ฌธ์ ๋คํ์ฑ์ ๋ง์กฑํ๋ ๊ฒ์ด์ง์.
๋์ ์ ๋ฆฌ
CGLIB๋ผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก ๋ด ํด๋์ค๋ฅผ ์์ ๋ฐ์ ๊ฐ์ง ํ๋ก์ ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด์ ์ฃผ์ ํ๋ ๊ฒ์ด์์.
์ด ๊ฐ์ง ํ๋ก์ ๊ฐ์ฒด๋ ์ค์ ์์ฒญ์ด ์ค๋ฉด ๊ทธ ๋ ๋ด๋ถ์์ ์ค์ Bean์ ์์ฒญํ๋ ์์ ๋ก์ง์ด ๋ค์ด ์๋ต๋๋ค!
๊ฐ์ง ํ๋ก์ ๊ฐ์ฒด๋ ์ค์ request Scope์๋ ๊ด๊ณ๊ฐ ์๋ ๊ฒ์ด์์. ๊ทธ๋ฅ ๊ฐ์ง์ด๊ณ , ๋ด๋ถ์ ๋จ์ํ ์์ ๋ก์ง๋ง ์์ผ๋ฉฐ, ์ด๊ฒ์ ์ฑ๊ธํค์ฒ๋ผ ๋์ํ๋ ๊ฒ์ด์์.
ํน์ง ์ ๋ฆฌ
ํ๋ก์ ๊ฐ์ฒด ๋๋ถ์ ํด๋ผ์ด์ธํธ๋ ๋ง์น ์ฑ๊ธํค Bean์ ์ฌ์ฉํ๋ฏ ํธ๋ฆฌํ๊ฒ request Scope๋ฅผ ์ฌ์ฉํ ์ ์๋ ๊ฒ์ด์์.
์ฌ์ค Provider๋ฅผ ์ฌ์ฉํ๋ Proxy๋ฅผ ์ฌ์ฉํ๋ ํต์ฌ์ ์ง์ง ๊ฐ์ฒด ์กฐํ๋ฅผ ๊ผญ ํ์ํ ์์ ๊น์ง ์ง์ฐ์ฒ๋ฆฌ ํ๋ค๋ ๊ฒ์ด๋๋๋ค. ๋จ์ง ์ด๋ ธํ ์ด์ ์ค์ ๋ณ๊ฒฝ๋ง์ผ๋ก ์๋ณธ ๊ฐ์ฒด๋ฅผ ํ๋ก์ ๊ฐ์ฒด๋ก ๋์ฒดํ ์ ์๋ ๊ฒ์ด์์. ์ด๊ฒ์ด ๋ฐ๋ก ๋คํ์ฑ๊ณผ DI ์ปจํ ์ด๋๊ฐ ๊ฐ์ง ํฐ ์ฅ์ ์ด๋๋๋ค.
๊ผญ ์น ์ค์ฝํ๊ฐ ์๋์ด๋ ํ๋ก์๋ ์ฌ์ฉํ ์ ์๋ ๊ฒ์ด์์.
์ฃผ์์
๋ง์น ์ฑ๊ธํค์ ์ฌ์ฉํ๋ ๊ฒ ๊ฐ์ง๋ง, ๋ค๋ฅด๊ฒ ๋์ํ๊ธฐ ๋๋ฌธ์ ์ฃผ์ํด์ ์ฌ์ฉํด์ผ ํ๋ ๊ฒ์ด์์. ์ด๋ฐ ํน๋ณํ ์ค์ฝํ๋ ๊ผญ ํ์ํ ๊ณณ์๋ง ์ต์ํํด์ ์ฌ์ฉํด์ผ ํ๋ต๋๋ค. ๋ฌด๋ถ๋ณํ๊ฒ ์ฌ์ฉํ๋ฉด ๋์ค์ ์ ์ง๋ณด์ํ ๋ ํ ๋์ค๋ ๊ฒ์ด์์.
์ฃผ๋ํ๋์ ๊ธ์ด ๋ง์์ ๋์ จ๋์? ๊ตฌ๋ ๊ณผ ๊ณต๊ฐ! ๊ทธ๋ฆฌ๊ณ , ๋๊ธ ๊ทธ๋ฆฌ๊ณ ๋ฐฉ๋ช ๋ก์ ์ฃผ๋ํ๋์๊ฒ ๋ง์ ํ์ด ๋ฉ๋๋ค.
'Back-End ์์ ์ค > Spring Framework' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| [Spring] Spring MVC๋? (0) | 2021.12.20 |
|---|---|
| [Spring] @Builder (Builder Patter) (0) | 2021.10.11 |
| [Spring] Bean Life Cycle Call Back (0) | 2021.10.08 |
| [Spring] ์์กด๊ด๊ณ ์ฃผ์ ๋ฐฉ๋ฒ (0) | 2021.10.07 |
| [Spring] Component Scan And Auto wired Start (0) | 2021.10.06 |