1. Bean scope๋?
- ๋น์ด ์กด์ฌํ ์ ์๋ ๋ฒ์๋ฅผ ๋ปํ๋ค. ์คํ๋ง ๋น์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ฑ๊ธํค scope๋ก ์์ฑ๋๋ค.
2. ์คํ๋ง์ด ์ง์ํ๋ ์ค์ฝํ ์ข ๋ฅ
(1) ์ฑ๊ธํค: ๊ธฐ๋ณธ ์ค์ฝํ์ด๋ฉฐ, ์คํ๋ง ์ปจํ ์ด๋์ ์์๊ณผ ์ข ๋ฃ๊น์ง ์ ์ง๋๋ ๊ฐ์ฅ ๋์ ๋ฒ์์ scope
(2) ํ๋กํ ํ์ : ์คํ๋ง ์ปจํ ์ด๋๋ ํ๋กํ ํ์ ๋น์ ์์ฑ๊ณผ ์์กด๊ด๊ณ ์ฃผ์ ๊น์ง๋ง ๊ด์ฌํ๊ณ ๋์ด์ ๊ด๋ฆฌํ์ง ์๋ ์งง์ ๋ฒ์์ scope
(3) ์น
์ฑ๊ธํค ์ค์ฝํ๋ฅผ ์ ์ธํ ์ค์ฝํ๋ ์ง์ง ํ์ํ ๊ณณ์์๋ง ์ฌ์ฉํด์ผ ์ ์ง๋ณด์๊ฐ ํธํ๋ค ๋ผ๋ ๋ง์ ์์์ผ๋ก ํ๋ฒ ์ ๋ฆฌํด๋ณด์!
3-1. Prototype Scope
- ์คํ๋ง ์ปจํ ์ด๋์ ์กฐํํ๋ฉด ์คํ๋ง ์ปจํ ์ด๋๋ ํญ์ ์๋ก์ด ์ธ์คํด์ค๋ฅผ ์์ฑํด์ ๋ฐํํ๋ค.
- ํด๋ผ์ด์ธํธ๊ฐ prototype scope์ ๋น์ ์์ฒญํ๋ฉด ๊ทธ๋์์ผ ์๋ก์ด ๋น์ ์์ฑํ๊ณ ํ์ํ ์์กด๊ด๊ณ๋ฅผ ์ฃผ์ ํ์ฌ ๋น์ ๋ฐํํด์ค๋ค. ๊ทธ ํ์๋ ๊ด๋ฆฌ๋ฅผ ํด์ฃผ์ง ์๋๋ค.
- ํด๋ผ์ด์ธํธ๋ง๋ค ์๋ก ๋ค๋ฅธ ์๋ก์ด ๋น์ ๋ง๋ค์ด์ ์ค๋ค.
์คํ๋ง ์ปจํ ์ด๋๋ Prototype Bean์ ์์ฑํ๊ณ , DIํ๊ณ , ์ด๊ธฐํ๊น์ง๋ง ์ฒ๋ฆฌํ๋ค.
ํด๋ผ์ด์ธํธ์ Bean์ ๋ฐํํ๊ณ ๋์ ์คํ๋ง ์ปจํ ์ด๋๋ ๋์ด์ Prototype Bean์ ๋ํด์ ๊ด๋ฆฌ๋ฅผ ํ์ง ์๊ธฐ ๋๋ฌธ์ ๊ด๋ฆฌ ์ฑ ์์ ์ด์ ๋น์ ๋ฐ์ ํด๋ผ์ด์ธํธ์ ์๋ค.
๋ฐ๋ผ์ @PreDestroy๊ฐ์ ์ข ๋ฃ ๋ฉ์๋๋ ํธ์ถ๋์ง ์๋๋ค.
3-2. Singleton Bean์์ Prototype Bean์ ์ฃผ์ ๋ฐ๋๊ฒฝ์ฐ ๋ฌธ์
๊ฐ์ ์ํฉ
๋ง์ฝ singletonBean์ด๋ผ๋ ์ฑ๊ธํค ๋น์ด ๋ด๋ถ์ prototypeBean์ ๋ฉค๋ฒ๋ก ๊ฐ์ง๊ณ ์์ ๋ ์คํ๋ง ์ปจํ ์ด๋ ์์ฑ ์์ ์ ํจ๊ป ์์ฑ๋๊ณ ์์กด๊ด๊ณ ์ฃผ์ ์ด ๋ฐ์ํ๋ค.
1. DI ์๋ ์ฃผ์ ์์ ์ ์คํ๋ง ์ปจํ ์ด๋์ prototypeBean์ ์์ฒญํ๋ค.
2. ์คํ๋ง ์ปจํ ์ด๋๋ prototypeBean์ ์์ฑํด์ singletonBean์ ๋ฐํํ๋ค.
๊ทธ๋ฆฌ๊ณ prototypeBean์ count๋ผ๋ ๋ฉค๋ฒ๊ฐ ์๊ณ ๊ธฐ๋ณธ ๊ฐ์ด 0์ด๋ค.
์ด์ singletonBean์ prototypeBean์ ๋ด๋ถ ํ๋์ ๋ณด๊ดํ๋ค. (์ ํํ๋ ์ฐธ์กฐ๊ฐ์ ๋ณด๊ด)
3. ํด๋ผ์ด์ธํธ A๋ singletonBean์ ์คํ๋ง ์ปจํ ์ด๋์ ์์ฒญํด์ ๋ฐ๋๋ค. ๊ทธ๋ฆฌ๊ณ singletonBean์ ๋ก์ง์ค ํ๋์ธ prototypeBean์ count๋ฅผ ์ฆ๊ฐ์ํค๋ addCount()๋ฅผ ๋ด๋ถ์์ ํธ์ถํ๋ singletonBean.logic()์ ํธ์ถํ๋ค.
4. singletonBean์ prototypeBean์ addCount()๋ฅผ ํธ์ถํด์ prototypeBean์ count๋ฅผ ์ฆ๊ฐ์์ผ count๋ 1์ด ๋๋ค.
5. ํด๋ผ์ด์ธํธ B๋ singletonBean์ ์คํ๋ง ์ปจํ ์ด๋์ ์์ฒญํด์ ๋ฐ๋๋ค. ์ฑ๊ธํค์ด๋ฏ๋ก ํญ์ ๊ฐ์ singletonBean์ด ๋ฐํ๋๋ค.
singletonBean์ด ๋ด๋ถ์ ๊ฐ์ง๊ณ ์๋ prototypeBean์ ์ด๋ฏธ ์ด์ ์ ์ฃผ์ ์ด ๋๋ ๋น์ด๋ค. singletonBean์ ์์กด๊ด๊ณ ์ฃผ์ ์์ ์ ์คํ๋ง ์ปจํ ์ด๋์ ์์ฒญํด์ prototypeBean์ด ์๋ก ์์ฑ์ด ๋ ๊ฒ์ด์ง, ์ฌ์ฉ ํ ๋๋ง๋ค ์๋ก ์์ฑ๋๋๊ฒ ์๋!
๋ฐ๋ผ์ ์ฑ๊ธํค ๋น์ ํ๋กํ ํ์ ๋น์ด ๋ด๋ถ ํ๋๋ก ๊ฐ์ง๊ณ ์๋ค๊ณ ํด์ ์ฑ๊ธํค ๋น์ด ํธ์ถ๋ ๋๋ง๋ค ํ๋กํ ํ์ ๋น์ด ์๋ก ์์ฑ๋๋๊ฒ ์๋.
6. ํด๋ผ์ด์ธํธ B๋ singletonBean.logic()์ ํธ์ถํ๋ค.
7. singletonBean.logic()์ ๋ด๋ถ์์ prototypeBean์ addCount()๋ฅผ ํธ์ถํด์ prototypeBean์ count๋ฅผ ์ฆ๊ฐ์ํจ๋ค. ๋ฐ๋ผ์ count๋ 2๊ฐ ๋๋ค.
๋ฌธ์
ํ๋กํ ํ์ ๋น์ ์ด๋ค๋ฉด ์ด๋ฐ ์ํฉ์ ๊ธฐ๋ํ๊ณ ์ฐ๋๊ฒ ์๋ ๊ฒ์ด๋ค. ์ด๋ด๊ฑฐ๋ฉด ์ฑ๊ธํค์ ์ฐ์ง ์ ํ๋กํ ํ์ ์ ์ฐ๊ฒ ๋?
์คํ๋ง์ ์ผ๋ฐ์ ์ผ๋ก ์ฑ๊ธํค ๋น์ ์ฌ์ฉํ๋ค.
์ฑ๊ธํค ๋น์ด ํ๋กํ ํ์ ๋น์ ์ฌ์ฉํ๋ฉด ์ฑ๊ธํค ๋น์ ์์ฑ ์์ ์๋ง DI๋ฅผ ํ๊ธฐ ๋๋ฌธ์ ํ๋กํ ํ์ ๋น์ ์๋ก ์์ฑ๋๊ธฐ๋ ํ์ง๋ง ๊ณ์ ์ฑ๊ธํค ๋น๊ณผ ํจ๊ป ์ ์ง๊ฐ ๋๋ค.
ํ๋กํ ํ์ ๋น์ ์ฃผ์ ์์ ์๋ง ์๋ก ์์ฑํ๋๊ฒ ์๋๋ผ ์ฌ์ฉํ ๋๋ง๋ค ์๋ก ์์ฑํด์ ์ฌ์ฉํ๊ธฐ๋ฅผ ์ํด์ ํ๋กํ ํ์ ๋น์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง๋ค.
ํด๊ฒฐ๋ฒ
1. Singletone Bean์ด Prototype์ ์ฌ์ฉํ ๋๋ง๋ค ์คํ๋ง ์ปจํ ์ด๋์ ์๋ก ์์ฒญ์ ํ๋ค.
@Scope("singleton")
static class SingletonBean{
@Autowired
ApplicationContext applicationContext;
public int logic(){
PrototypeBean prototypeBean = applicationContext.getBean(PrototypeBean.class);
prototypeBean.addCount();
int count = prototypeBean.getCount();
return count;
}
}
- ์์กด๊ด๊ณ๋ฅผ ์ธ๋ถ์์ ์ฃผ์
(DI) ๋ฐ๋๊ฒ ์๋๋ผ ์ด๋ฐ ์์ผ๋ก ์ง์ ํ์ํ ์์กด๊ด๊ณ๋ฅผ ์ฐพ๋ ๊ฒ์ ์์กด๊ด๊ณ ํ์ Dependency Lookup (DL) ์ด๋ผ๊ณ ํ๋ค.
- ์ด๋ฐ์์ผ๋ก Spring์ ApplicationContext ์ ์ฒด๋ฅผ ์ฃผ์ ๋ฐ์ ๋ฒ๋ฆฌ๋ฉด, Spring Container์ ์ข ์์ ์ด๊ฒ ๋๋ฒ๋ฆฌ๊ณ ๋จ์ ํ ์คํธ๊ฐ ์ด๋ ค์์ง๋ค.
2. ObjectFactory, ObjectProvider ์ฌ์ฉ
@Scope("singleton")
static class ClientBean{
@Autowired
private ObjectProvider<PrototypeBean> prototypeBeanProvider;
public int logic(){
PrototypeBean prototypeBean = prototypeBeanProvider.getObject();
prototypeBean.addCount();
int count = prototypeBean.getCount();
return count;
}
}
- ObjectProvider๊ฐ ObjectFactory๋ฅผ ์์๋ฐ๋ ๊ตฌ์กฐ๋ก ๋ ๋ค getObject()๋ฅผ ํตํด ๋น์ ๊ฐ์ ธ์ฌ ์ ์๋๋ฐ, ์ฌ๊ธฐ์๋ ํ๋กํ ํ์ ๋น์ ๊ฐ์ ธ์ค๋ฏ๋ก ํญ์ ์๋ก์ด ํ๋กํ ํ์ ๋น์ ์์ฑ๋์ด ๊ฐ์ ธ์ฌ ์ ์๋ค. ObjectProvider๊ฐ ObjectFactory๋ณด๋ค ๊ธฐ๋ฅ์ ๋ ์ ๊ณตํด์ค๋ค๊ณ ์๊ฐํ๋ฉด ๋๋ค.
- ํ์ง๋ง ObjectProvider๋ ํ๋กํ ํ์ ์ ์ฉ์ด๋ผ๊ณ ์๊ฐํ๋ฉด ์๋๊ณ ์คํ๋ง ์ปจํ ์ด๋๋ฅผ ํตํด์ DL์ ๊ฐ๋จํ๊ฒ ๋์์ฃผ๋ ๋๋ฆฌ์ ์ ๋๋ก ์๊ฐํ๋ฉด ๋๋ค.
- 1๋ฒ์ฒ๋ผ์ด ์๋๋ผ ์ฐ๋ฆฌ๋ DL ์์กด๊ด๊ณ ํ์ ์ ๋์ ๊ธฐ๋ฅ์ด ํ์ํ๊ฑด๋ฐ ๊ทธ๊ฑธ ์ ๊ณตํด์ฃผ๋๊ฒ ObjectProvider์ด๋ค.
- ObjectFactory: ๋จ์ํ ๊ธฐ๋ฅ๋ง ์ ๊ณต, ๋ณ๋์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ํ์ X. ์คํ๋ง์ ์์กด
- ObjectProvider: ObjectFactory๋ฅผ ์์๋ฐ์, ์ต์ , ์คํธ๋ฆผ ์ฒ๋ฆฌ ๋ฑ ํธ๋ฆฌํ ๊ธฐ๋ฅ์ ๋ง์ด ์ ๊ณต, ๋ณ๋์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ํ์ X, ์คํ๋ง์ ์์กด
import org.springframework.beans.factory.ObjectProvider;
์คํ๋ง์ ์์กด์ ์ด๋ผ๋ ๋จ์ ์ด ์๋ค.
3. JSR-330 Provider
javax.inject.Provider๋ผ๋ JSR-330 ์๋ฐ ํ์ค์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ
์ฌ์ฉํ๊ธฐ ์ํด 'javax.inject:javax.inject:1' ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ gradle์ ์ถ๊ฐํด์ผ ํจ.
implementation 'javax.inject:javax.inject:1'
import javax.inject.Provider;
@Scope("singleton")
static class ClientBean{
@Autowired
private Provider<PrototypeBean> prototypeBeanProvider;
public int logic(){
PrototypeBean prototypeBean = prototypeBeanProvider.get();
prototypeBean.addCount();
int count = prototypeBean.getCount();
return count;
}
}
- Provider์ get()์ ํธ์ถํ๋ฉด ๋ด๋ถ์์๋ DL๊ฐ๋ ์ผ๋ก ์คํ๋ง ์ปจํ ์ด๋๋ฅผ ํตํด ํด๋น ๋น์ ์ฐพ์์ ๋ฐํํ๋ค.
- ์๋ฐ ํ์ค ๋ฐฉ๋ฒ์ด๊ณ ๊ธฐ๋ฅ์ด ์ ๋ง ๋จ์ํด์ ๋จ์ํ ์คํธ๋ฅผ ๋ง๋ค๊ฑฐ๋ Mock ์ฝ๋๋ฅผ ๋ง๋ค๊ธฐ ํจ์ฌ ์ฝ๋ค.
- ObjectProvider๋ ์คํ๋ง์ ์์กด์ ์ด๊ณ ๋ค๋ฅธ ๊ธฐ๋ฅ๋ค์ด ๋ง์ด ์๋ ๋ฐ๋ฉด, Provider๋ ์ ๋ง ํ์ํ DL ํ๋์ ๊ธฐ๋ฅ ์ ๋๋ง ์ ๊ณตํ๋ค.
- ๋ณ๋์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ํ์ํ๋ค.
- ์คํ๋ง์ ์์กด์ ์ด์ง ์์ผ๋ฏ๋ก ์คํ๋ง์ด ์๋ ๋ค๋ฅธ ์ปจํ ์ด๋์์๋ ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋ค.
3-3. ์ธ์ ํ๋กํ ํ์ ๋น์ ์ฌ์ฉํ ๊น?
- ๋งค๋ฒ ์ฌ์ฉํ ๋ ๋ง๋ค ์์กด๊ด๊ณ ์ฃผ์ ์ด ์๋ฃ๋ ์๋ก์ด ๊ฐ์ฒด๊ฐ ํ์ํ ๋ ์ฌ์ฉํ๋ฉด ๋๋ค.
- ํ์ง๋ง ์ฑ๊ธํค ๋น์ผ๋ก ๋๋ถ๋ถ์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๊ธฐ ๋๋ฌธ์ ํ๋กํ ํ์ ๋น์ ์ง์ ์ ์ผ๋ก ์ฌ์ฉํ๋ ์ผ์ ๋งค์ฐ ๋๋ฌผ๋ค.
์ฐธ๊ณ ) ObjectProvider, Provider๋ ํ๋กํ ํ์ ์์๋ง ์ฌ์ฉํ๋๊ฒ ์๋๋ผ DL์ด ํ์ํ ์ํฉ์ ์ด๋๋ ์ง ์ฌ์ฉ ๊ฐ๋ฅํ๋ค.
3-4. ObjectProvider VS Provider
- ObjectProvider๋ DL์ ์ํ ํธ์ ๊ธฐ๋ฅ์ ์ฌ๋ฌ ์ ๊ณตํด์ฃผ๊ณ ์คํ๋ง ์ธ์ ๋ณ๋์ gradle์ ์์กด์ฑ์ ์ถ๊ฐํ๊ณ ํ๋ ์ผ์ด ํ์ ์์ด์ ํธ๋ฆฌํ๋ค.
- Provider๋ ์คํ๋ง์ ์์กด์ ์ด์ง ์๊ณ ์๋ฐ ํ์ค์ด๋ฏ๋ก ์ฝ๋๋ฅผ ์คํ๋ง์ด ์๋ ๋ค๋ฅธ ์ปจํ ์ด๋์์๋ ์ฌ์ฉํ ์ ์์ด์ผ ํ ๋ ์ฌ์ฉํ๋ค.(๊ฑฐ์ ์๋ ์ผ) ๊ทธ๋ฐ๋ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ค์นํด์ผํ๋ ๋ถํธํจ..
๋๋ถ๋ถ ์คํ๋ง์ด ๋ ๋ค์ํ๊ณ ํธ๋ฆฌํ ๊ธฐ๋ฅ์ ์ ๊ณตํด์ฃผ๋ฏ๋ก ํน๋ณํ ๋ค๋ฅธ ์ปจํ ์ด๋๋ฅผ ์ฌ์ฉํ ์ผ์ด ์๋ค๋ฉด, ์คํ๋ง์ด ์ ๊ณตํ๋ ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ฉด ๋๋ค.
4. Web Scope
- ์น ํ๊ฒฝ์์๋ง ๋์
- ํ๋กํ ํ์ ๊ณผ ๋ค๋ฅด๊ฒ ์คํ๋ง์ด ํด๋น ์ค์ฝํ์ ์ข ๋ฃ์์ ๊น์ง ๊ด๋ฆฌํ๋ฏ๋ก ์ข ๋ฃ ๋ฉ์๋๊ฐ ํธ์ถ๋จ.
์น ์ค์ฝํ ์ข ๋ฅ
1. request: HTTP ์์ฒญ์ด ํ๋ ๋ค์ด์ค๊ณ ๋๊ฐ ๋ ๊น์ง ์ ์ง.
๊ฐ๊ฐ์ HTTP ์์ฒญ๋ง๋ค ๋ณ๋์ ๋น ์ธ์คํด์ค๊ฐ ์์ฑ๋๊ณ ๊ด๋ฆฌ๋๋ค.
2. session: HTTP Session๊ณผ ๋์ผํ ์๋ช ์ฃผ๊ธฐ๋ฅผ ๊ฐ์ง๋ค.
3. application: ์น์ Servletcontext์ ๋์ผํ ์๋ช ์ฃผ๊ธฐ๋ฅผ ๊ฐ์ง๋ค.
4. websocket: ์น Socket๊ณผ ๋์ผํ ์๋ช ์ฃผ๊ธฐ๋ฅผ ๊ฐ์ง๋ค.
4-1. Request Scope Example
web scope๋ ์น ํ๊ฒฝ์์๋ง ๋์ํ๊ธฐ ๋๋ฌธ์ web ํ๊ฒฝ์ด ๋์ํ๋๋ก ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ถ๊ฐํด์ผ ํ๋ค.
implementation 'org.springframework.boot:spring-boot-starter-web'
๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ถ๊ฐํ๋ฉด Spring Boot๋ ๋ด์ฅ ํฐ์บฃ ์๋ฒ๋ฅผ ํ์ฉํด์ ์น ์๋ฒ์ ์คํ๋ง์ ํจ๊ป ์คํ์ํจ๋ค.
์ฐธ๊ณ ) ์คํ๋ง ๋ถํธ๋ ์น ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์์ ๋๋ AnnotationConfigApplicationContext๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ๋ํ์ง๋ง, ์น ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์ถ๊ฐ๋๋ฉด ์น๊ณผ ๊ด๋ จ๋ ์ถ๊ฐ ์ค์ ๊ณผ ํ๊ฒฝ๋ค์ด ํ์ํ๋ฏ๋ก AnnotationConfigServletWebServerApplicationContext๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ๋ํ๋ค.
์์ ์ค๋ช : ๋์์ ์ฌ๋ฌ HTTP ์์ฒญ์ด ์ค๋ฉด ์ ํํ ์ด๋ค ์์ฒญ์ด ๋จ๊ธด ๋ก๊ทธ์ธ์ง ๊ตฌ๋ถํ๊ธฐ ์ด๋ ค์ฐ๋ฏ๋ก request scope๋ฅผ ์ด์ฉํ์ฌ UUID๋ฅผ ๋ก๊ทธ ๋ฌธ์ฅ์ ์ถ๊ฐํ์ฌ ์ ํํ ๋ก๊ทธ๋ฅผ ๋จ๊ธฐ๋ ์์ .
MyLogger์ requestURL์ ์ ์ฅํด๋๋๋ฐ MyLogger๋ ์ค์ฝํ๊ฐ request์ด๋ฏ๋ก HTTP ์์ฒญ ๋น ๊ฐ๊ฐ ๊ตฌ๋ถ๋๋ฏ๋ก ๋ค๋ฅธ HTTP ์์ฒญ ๋๋ฌธ์ ๊ฐ์ด ์์ด๋ ๊ฑฑ์ ์ ํ์ง ์์๋ ๋๋ค.
@Component
@Scope(value = "request")
public class MyLogger {
private String uuid;
private String requestURL;
public void setRequestURL(String requestURL) {
this.requestURL = requestURL;
}
public void log(String message){
System.out.println("[" + uuid + "][" + requestURL +"] " + message );
}
@PostConstruct
public void init(){
uuid = UUID.randomUUID().toString();
System.out.println("[" + uuid + "] request scope bean create: " + this);
}
@PreDestroy
public void close(){
System.out.println("[" + uuid + "] request scope bean close: " + this);
}
}
@Controller
@RequiredArgsConstructor
public class LogDemoController {
private final LogDemoService logDemoService;
private final MyLogger myLogger;
@RequestMapping("log-demo")
@ResponseBody
public String logDemo(HttpServletRequest request){
String requestURL = request.getRequestURL().toString();
myLogger.setRequestURL(requestURL);
myLogger.log("controller test");
logDemoService.logic("testId");
return "OK";
}
}
@Service
@RequiredArgsConstructor
public class LogDemoService {
private final MyLogger myLogger;
public void logic(String id) {
myLogger.log("service id = " + id);
}
}
- request scope๋ฅผ ์ฌ์ฉํ์ง ์๊ณ ํ๋ผ๋ฏธํฐ๋ก requestURL๊ฐ์ ๋ชจ๋ ์ ๋ณด๋ฅผ ์๋น์ค ๊ณ์ธต์ผ๋ก ๋๊ธฐ๋ฉด ํ๋ผ๋ฏธํฐ๊ฐ ๋ง์์ ์ง์ ๋ถํด์ง๊ณ ์น๊ณผ ๊ด๋ จ์๋ ์๋น์ค ๊ณ์ธต์ ์ด๋ฌํ ์ ๋ณด๋ค์ด ๋ค์ด์ค๋ ๊ฒ์ ๋ฌธ์ ๊ฐ ๋๋ค.
- ์น๊ณผ ๊ด๋ จ๋ ๋ถ๋ถ์ ์ปจํธ๋กค๋ฌ๊น์ง๋ง ์ฌ์ฉํด์ผ ํ๋ค.
- ์๋น์ค ๊ณ์ธต์ ์น ๊ธฐ์ ์ ์ข ์๋์ง ์๊ณ ์์ํ๊ฒ ์ ์งํ๋ ๊ฒ์ด ์ ์ง๋ณด์ ๊ด์ ์์ ์ข๋ค.
- MyLogger๋ฅผ request scope๋ก ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ์ฝ๋์ ๊ณ์ธต์ ๊น๋ํ๊ฒ ์ ์งํ ์ ์๋ค.
์ด๋๋ก ์คํํ๋ฉด ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค.
request Scope ๊ด๋ จํด์ ์ค๋ฅ๊ฐ ๋๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
๋ฌธ์
์๋ํ๋ฉด request scope๋ ์์์ ๋งํ๋ฏ์ด ์ฌ์ฉ์์ http ์์ฒญ์ด ๋ค์ด์ฌ ๋ ๋น์ด ์์ฑ๋๋ค๊ณ ํ๋๋ฐ ์์ฒญ์ด ๋ค์ด์ค์ง๋ฅผ ์์๋๋ฐ Controller์ Service์ ์๋ ์ฃผ์ ํด์ฃผ๋ ค๊ณ ํ๋ ๋ฌธ์ ๊ฐ ์๊ธฐ๋ ๊ฒ์ด๋ค.
๋ฐ๋ผ์ request scope์ ๋น์ ๋ฐ๋ ๊ฒ์ ์ฌ์ฉ์์ ์์ฒญ์ด ์ ๋ ฅ๋ ๋๋ก ๋ฏธ๋ค์ผ ํ๋ค. ๋ฌด์์ ์ฌ์ฉํด์ผ ํ ๊น?
๋ฌธ์ ํด๊ฒฐ๋ฒ
1. ObjectProvider ์ฌ์ฉ
ObjectProvider๋ฅผ ์ด์ฉํ์ฌ HTTP ์์ฒญ์ด ๋ค์ด์ฌ ๋ getObjectํด์ DLํ์ฌ ๋น์ ์ฐพ์์จ๋ค.
ObjectProvider.getObject()๋ฅผ ํธ์ถํ๋ ์์ ์๋ HTTP ์์ฒญ์ด ์งํ์ค์ด๋ฏ๋ก request scope์ ๋น์ ์์ฑ์ด ์ ์์ฒ๋ฆฌ๋๋ฏ๋ก ์ฐพ์์ฌ ์ ์๋ ๊ฒ์.
@Controller
@RequiredArgsConstructor
public class LogDemoController {
private final LogDemoService logDemoService;
private final ObjectProvider<MyLogger> myLoggerProvider;
@RequestMapping("log-demo")
@ResponseBody
public String logDemo(HttpServletRequest request){
String requestURL = request.getRequestURL().toString();
MyLogger myLogger = myLoggerProvider.getObject();
myLogger.setRequestURL(requestURL);
myLogger.log("controller test");
logDemoService.logic("testId");
return "OK";
}
}
์์ ๊ฐ์ด Service๋ ObjectProvider๋ฅผ ์ฌ์ฉํ๋๋ก ๋ณ๊ฒฝํ๋ฉด ์ ์์ ์ผ๋ก ๋์ํ๋ค.
2. Proxy ์ฌ์ฉ(์น ์ค์ฝํ์์๋ง ์ฌ์ฉํ ์ ์๋๊ฑด ์๋)
MyLogger์ ๋๋ฆฌ์(๊ฐ์ง) Proxy ํด๋์ค๋ฅผ ๋ง๋ค์ด๋๊ณ HTTP request์ ์๊ด ์์ด ๊ฐ์ง ํ๋ก์ ํด๋์ค๋ฅผ ๋ค๋ฅธ ๋น์ ๋ฏธ๋ฆฌ ์ฃผ์ ํด ๋ ์ ์๋ค.
@Component
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class MyLogger {
private String uuid;
private String requestURL;
...
}
Scope์ proxyMode ์ต์ ์ ์ค์ ํด์ฃผ๋ฉด ๋๋ค.
- ์ ์ฉ ๋์(์ฌ๊ธฐ์๋ MyLogger)์ด class์ด๋ฉด TARGET_CLASS
- ์ ์ฉ ๋์์ด ์ธํฐํ์ด์ค์ด๋ฉด INTERFACES ๋ฅผ ์ ํ
๋จ์ง annotation ์ค์ ์ ์ถ๊ฐํ ๊ฒ๋ง์ผ๋ก ์๋ณธ ๊ฐ์ฒด๋ฅผ Proxy๋ก ๋์ฒดํ ์ ์๋ ๊ฒ์ด๋ค. ์ฌ๊ธฐ์ ๋คํ์ฑ๊ณผ DI ์ปจํ ์ด๋๊ฐ ๊ฐ์ง ํฐ ์ฅ์ ์ ์ ์ ์๋ค.
๋ก๊ทธ๋ฅผ ์ฐ์ด๋ณด๋ฉด CGLIB ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํตํด ๋ด ํด๋์ค๋ฅผ ์์๋ฐ์ ๊ฐ์ง Proxy ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด์ ์ฃผ์ ํ ๊ฒ์ ๋ณผ ์ ์๋ค.
- @Scope์ proxMode๋ฅผ ์ค์ ํ๋ฉด ์คํ๋ง ์ปจํ ์ด๋๋ CGLIB๋ผ๋ ๋ฐ์ดํธ ์ฝ๋๋ฅผ ์กฐ์ํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ MyLogger๋ฅผ ์์๋ฐ์ ๊ฐ์ง Proxy ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ค.
- ๊ทธ๋ฆฌ๊ณ ์คํ๋ง ์ปจํ ์ด๋์ myLogger๋ผ๋ ์ด๋ฆ์ผ๋ก ์ง์ง ๋์ ์ ๊ฐ์ง Proxy ๊ฐ์ฒด๋ฅผ ๋ฑ๋กํ๋ค.
- ๋ฐ๋ผ์ DI ์์๋ ์ด ๊ฐ์ง Proxy ๊ฐ์ฒด๊ฐ ์ฃผ์ ๋๋ค.
๋๋ฆฌ์(๊ฐ์ง) Proxy ๊ฐ์ฒด๋ ์์ฒญ์ด ์ค๋ฉด ๊ทธ๋์์ผ ๋ด๋ถ์์ ์ง์ง Bean์ ์์ฒญํ๋ ์์ logic์ด ๋ค์ด์๋ค.
- ๊ฐ์ง Proxy Bean์ ๋ด๋ถ์ ์ค์ MyLogger์ ์ง์ง Bean์ ์ฐพ๋ ๋ฐฉ๋ฒ์ ์๊ณ ์๋ค.
- ํด๋ผ์ด์ธํธ๊ฐ MyLogger.logic()์ ํธ์ถํ๋ฉด ์ค์ ๋ก๋ ๊ฐ์ง Proxy ๊ฐ์ฒด์ ๋ฉ์๋๋ฅผ ํธ์ถํ ๊ฒ์ด๋ค.
- ๊ฐ์ง Proxy ๊ฐ์ฒด๋ request scope์ ์ง์ง myLogger.logic()์ ๋ด๋ถ์์ ํธ์ถํ๋ค.
- ๊ฐ์ง Proxy ๊ฐ์ฒด๋ ์์์ ๋งํ๋ฏ์ด ์๋ณธ ํด๋์ค๋ฅผ ์์ ๋ฐ์์ ๋ง๋ค์ด์ง๊ธฐ ๋๋ฌธ์ ์ด ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ๋ ํด๋ผ์ด์ธํธ ์ ์ฅ์์๋ ์๋ณธ์ธ์ง ์๋์ง๋ ๋ชจ๋ฅด๊ฒ ๋์ผํ๊ฒ ์ฌ์ฉํ ์ ์๋ค. (๋คํ์ฑ ๊ฐ๋ )
Proxy ๊ตฌ๋ ๋ฐฉ์ ์ ๋ฆฌ
1. CGLIB๋ผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก ๋ด ํด๋์ค๋ฅผ ์์ ๋ฐ์ ๊ฐ์ง ํ๋ก์ ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด์ ์ฃผ์ ํ๋ค.
2. ์ด ๊ฐ์ง Proxy ๊ฐ์ฒด๋ ์ค์ ์์ฒญ์ด ๋ค์ด์ค๋ฉด ๊ทธ๋ ๋ด๋ถ์์ ์ค์ ๋น์ ์์ฒญํ๋ ์์ ๋ก์ง์ด ๋ค์ด์๋ค.
3. ๊ฐ์ง Proxy ๊ฐ์ฒด๋ ์ค์ request scope์๋ ๊ด๊ณ ์์ด ๊ทธ๋ฅ ๊ฐ์ง์ด๊ณ ๋ด๋ถ์ ๋จ์ํ ์์ ๋ก์ง์ด ์๋๋ฐ ์ฑ๊ธํค ์ฒ๋ผ ๋์ํ๋ค. ๊ทธ๋ฐ๋ฐ ์ค์ ๋ก๋ ๋ด๋ถ์์๋ ์ฑ๊ธํค์ด ์๋๋ฏ๋ก ์ฃผ์ํด์ผ ํ๋ค.
Proxy ๊ฐ์ฒด ๋๋ถ์ ํด๋ผ์ด์ธํธ๋ ๋ง์น ์ฑ๊ธํค ๋น์ ์ฌ์ฉํ๋ฏ์ด ํธ๋ฆฌํ๊ฒ request scope๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
์ฐธ๊ณ ) Provider๋ฅผ ์ฌ์ฉํ๋์ง Proxy๋ฅผ ์ฌ์ฉํ๋์ง ํต์ฌ ์์ด๋์ด์ธ ์ง์ง ๊ฐ์ฒด ์กฐํ๋ฅผ ๊ผญ ํ์ํ ์์ ๊น์ง ์ง์ฐ์ฒ๋ฆฌํ๋ค๋๊ฒ ์ค์ํ๋ค.
'๐ Backend > ๐ Spring' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Path Variable VS Query Parameter (0) | 2022.07.29 |
---|---|
์๋ธ๋ฆฟ(Servlet)์ด ๋ฌด์์ธ์ง ๊ฐ์ด ์์๋ณด์! (0) | 2022.07.18 |
Spring DI 4๊ฐ์ง ๋ฐฉ๋ฒ๊ณผ ์ต์ ์ฒ๋ฆฌ (0) | 2022.07.08 |
IOC, DI, Container (0) | 2022.07.05 |
๊ฐ์ฒด์งํฅ ์ค๊ณ์ ์คํ๋ง (0) | 2022.07.02 |