Bean Scopes
Bean Scopes (๋น ์ค์ฝํ)
Bean ์ ์๋ฅผ ์์ฑํ ๋, ํด๋น Bean ์ ์์ ์ํด ์ ์๋ ํด๋์ค์ ์ค์ ์ธ์คํด์ค๋ฅผ ์์ฑํ๊ธฐ ์ํ "๋ ์ํผ"๋ฅผ ๋ง๋๋ ๊ฒ์ ๋๋ค. Bean ์ ์๊ฐ ๋ ์ํผ๋ผ๋ ๊ฐ๋ ์ ์ค์ํ๋ฉฐ, ์ด๋ ํด๋์ค์ ๋ง์ฐฌ๊ฐ์ง๋ก ๋จ์ผ ๋ ์ํผ์์ ์ฌ๋ฌ ๊ฐ์ฒด ์ธ์คํด์ค๋ฅผ ์์ฑํ ์ ์์์ ์๋ฏธํฉ๋๋ค.
Bean ์ ์์์ ํน์ Bean ์ ์๋ก ์์ฑ๋ ๊ฐ์ฒด์ ๋ค์ํ ์์กด์ฑ๊ณผ ๊ตฌ์ฑ ๊ฐ์ ์ ์ดํ ์ ์์ ๋ฟ๋ง ์๋๋ผ, ํน์ Bean ์ ์๋ก ์์ฑ๋ ๊ฐ์ฒด์ ๋ฒ์(scope)๋ ์ ์ดํ ์ ์์ต๋๋ค. ์ด ์ ๊ทผ ๋ฐฉ์์ ๊ฐ์ฒด์ ๋ฒ์๋ฅผ Java ํด๋์ค ์์ค์์ ๊ณ ์ ํ์ง ์๊ณ ๊ตฌ์ฑ(configuration)์ ํตํด ์ ํํ ์ ์๊ธฐ ๋๋ฌธ์ ๊ฐ๋ ฅํ๊ณ ์ ์ฐํฉ๋๋ค.
Spring Framework๋ ์ฌ์ฏ ๊ฐ์ง ๋ฒ์๋ฅผ ์ง์ํ๋ฉฐ, ๊ทธ ์ค ๋ค ๊ฐ์ง๋ ์น ์ธ์(ApplicationContext) ํ๊ฒฝ์์๋ง ์ฌ์ฉํ ์ ์์ต๋๋ค. ๋ํ, ์ฌ์ฉ์ ์ ์ ๋ฒ์๋ฅผ ์์ฑํ ์๋ ์์ต๋๋ค.
Bean Scopes
Scope
Description
singleton
(๊ธฐ๋ณธ๊ฐ) ๊ฐ Spring IoC ์ปจํ ์ด๋๋น ๋จ์ผ ๊ฐ์ฒด ์ธ์คํด์ค๋ก ์ค์ฝํ๋ฅผ ์ง์ ํฉ๋๋ค.
prototype
๋จ์ผ Bean ์ ์๋ฅผ ์ฌ๋ฌ ๊ฐ์ฒด ์ธ์คํด์ค๋ก ์ค์ฝํ๋ฅผ ์ง์ ํฉ๋๋ค.
request
๋จ์ผ HTTP ์์ฒญ์ ์๋ช ์ฃผ๊ธฐ์ Bean์ ์ค์ฝํํฉ๋๋ค. ์ฆ, ๊ฐ HTTP ์์ฒญ๋ง๋ค ๋จ์ผ Bean ์ ์๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์๋ก์ด ์ธ์คํด์ค๊ฐ ์์ฑ๋ฉ๋๋ค. ์ด๋ ์น ์ธ์ Spring ApplicationContext ํ๊ฒฝ์์๋ง ์ ํจํฉ๋๋ค.
session
HTTP ์ธ์ ์ ์๋ช ์ฃผ๊ธฐ์ Bean์ ์ค์ฝํํฉ๋๋ค. ์ด๋ ์น ์ธ์ Spring ApplicationContext ํ๊ฒฝ์์๋ง ์ ํจํฉ๋๋ค.
application
ServletContext์ ์๋ช ์ฃผ๊ธฐ์ Bean์ ์ค์ฝํํฉ๋๋ค. ์ด๋ ์น ์ธ์ Spring ApplicationContext ํ๊ฒฝ์์๋ง ์ ํจํฉ๋๋ค.
websocket
WebSocket์ ์๋ช ์ฃผ๊ธฐ์ Bean์ ์ค์ฝํํฉ๋๋ค. ์ด๋ ์น ์ธ์ Spring ApplicationContext ํ๊ฒฝ์์๋ง ์ ํจํฉ๋๋ค.
Thread scope๋ ์ฌ์ฉํ ์ ์์ง๋ง ๊ธฐ๋ณธ์ ์ผ๋ก ๋ฑ๋ก๋์ด ์์ง ์์ต๋๋ค. ์ด ๋๋ ๊ธฐํ ์ฌ์ฉ์ ์ ์ ์ค์ฝํ๋ฅผ ๋ฑ๋กํ๋ ๋ฐฉ๋ฒ์ ๋ํด์๋ Custom Scope ์ฌ์ฉํ๊ธฐ๋ฅผ ์ฐธ์กฐํ์ธ์.
Singleton Scope
์ฑ๊ธํค ๋ฒ์์ Bean์ ๋จ์ผ ๊ณต์ ์ธ์คํด์ค๋ง ๊ด๋ฆฌํ๋ฉฐ, ํด๋น Bean ์ ์์ ์ผ์นํ๋ ID๋ฅผ ๊ฐ์ง ๋ชจ๋ ์์ฒญ์ ๋ํด Spring ์ปจํ ์ด๋๊ฐ ๋์ผํ Bean ์ธ์คํด์ค๋ฅผ ๋ฐํํฉ๋๋ค.
๋ค์ ๋งํด, Bean ์ ์๋ฅผ ์ฑ๊ธํค์ผ๋ก ์ค์ฝํํ๋ฉด Spring IoC ์ปจํ ์ด๋๋ ํด๋น Bean ์ ์์ ์ํด ์ ์๋ ๊ฐ์ฒด์ ์ ํํ ํ๋์ ์ธ์คํด์ค๋ง ์์ฑํฉ๋๋ค. ์ด ๋จ์ผ ์ธ์คํด์ค๋ ์ฑ๊ธํค Bean ์บ์์ ์ ์ฅ๋๋ฉฐ, ์ดํ์ ๋ชจ๋ ์์ฒญ๊ณผ ์ฐธ์กฐ๋ ์บ์๋ ๊ฐ์ฒด๋ฅผ ๋ฐํํฉ๋๋ค.
Spring์ ์ฑ๊ธํค ๊ฐ๋ ์ Gang of Four(GoF) ํจํด ์ฑ ์์ ์ ์๋ ์ฑ๊ธํค ํจํด๊ณผ ๋ค๋ฆ ๋๋ค. GoF ์ฑ๊ธํค์ ClassLoader๋น ํ๋์ ์ธ์คํด์ค๋ง ์์ฑํ๋๋ก ๊ฐ์ฒด์ ๋ฒ์๋ฅผ ํ๋์ฝ๋ฉํฉ๋๋ค. ๋ฐ๋ฉด Spring ์ฑ๊ธํค์ ๋ฒ์๋ ์ปจํ ์ด๋ ๋ฐ Bean๋น ํ๋๋ก ์ค๋ช ํ ์ ์์ต๋๋ค.
์ด๋ ๋จ์ผ Spring ์ปจํ ์ด๋์ ํน์ ํด๋์ค์ Bean์ ํ๋ ์ ์ํ๋ฉด, ๊ทธ Bean ์ ์์ ์ํด ์ ์๋ ํด๋์ค์ ์ธ์คํด์ค๊ฐ ํ๋๋ง ์์ฑ๋จ์ ์๋ฏธํฉ๋๋ค. ์ฑ๊ธํค ์ค์ฝํ๋ Spring์์ ๊ธฐ๋ณธ ์ค์ฝํ์ ๋๋ค. XML์์ ์ฑ๊ธํค์ผ๋ก Bean์ ์ ์ํ๋ ์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
<bean id="accountService" class="com.something.DefaultAccountService"/>
<bean id="accountService" class="com.something.DefaultAccountService" scope="singleton"/>
@Component
class HomeController(
var data: String = "hello spring"
) {
}
------------------------------------------------------------------
@ExtendWith(SpringExtension::class)
@ContextConfiguration("file:web/WEB-INF/spring/applicationContext.xml")
class BeanScopeTest {
@Autowired
lateinit var homeController: HomeController
@Autowired
lateinit var applicationContext:ApplicationContext
@Test
fun test() {
homeController.data = "new one"
val bean = applicationContext.getBean("homeController") as HomeController
assertEquals("new one", bean.data) // ๋ณ๊ฒฝ๋ ๊ฐ ์ ์ง
}
}
Prototype Scope
ํ๋กํ ํ์
์ค์ฝํ๋ Bean ์ ์๋น ์๋ก์ด Bean ์ธ์คํด์ค๋ฅผ ์์ฑํ์ฌ ๋ฐํํฉ๋๋ค. ์ฆ, Bean์ ์ฃผ์
๋ฐ๊ฑฐ๋ getBean()
๋ฉ์๋๋ฅผ ํตํด Bean์ ์์ฒญํ ๋๋ง๋ค ์๋ก์ด ์ธ์คํด์ค๊ฐ ์์ฑ๋ฉ๋๋ค.
์ผ๋ฐ์ ์ผ๋ก ์ํ๋ฅผ ๊ฐ์ง๋(Stateful) Bean์๋ ํ๋กํ ํ์ ์ค์ฝํ๋ฅผ, ๋ฌด์ํ(Stateless) Bean์๋ ์ฑ๊ธํค ์ค์ฝํ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
XML์์ ํ๋กํ ํ์ ์ผ๋ก Bean์ ์ ์ํ๋ ์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค
<bean id="accountService" class="com.something.DefaultAccountService" scope="prototype"/>
@Component
class HomeController(
var data: String = "hello spring"
) {
}
------------------------------------------------------------------
@ExtendWith(SpringExtension::class)
@ContextConfiguration("file:web/WEB-INF/spring/applicationContext.xml")
class BeanScopeTest {
@Autowired
lateinit var homeController: HomeController
@Autowired
lateinit var applicationContext:ApplicationContext
@Test
fun test() {
homeController.data = "new one"
val bean = applicationContext.getBean("homeController") as HomeController
assertEquals("hello spring", bean.data) // ์ธ์คํด์ค ์ฌ์์ฑ
}
}
๋ค๋ฅธ ์ค์ฝํ์ ๋ฌ๋ฆฌ Spring์ ํ๋กํ ํ์ Bean์ ์ ์ฒด ์๋ช ์ฃผ๊ธฐ๋ฅผ ๊ด๋ฆฌํ์ง ์์ต๋๋ค. ์ปจํ ์ด๋๋ ํ๋กํ ํ์ ๊ฐ์ฒด๋ฅผ ์ธ์คํด์คํ, ์ค์ ๋ฐ ์กฐ๋ฆฝํ ํ ํด๋ผ์ด์ธํธ์ ์ ๋ฌํ๋ฉฐ, ๊ทธ ์ดํ๋ก๋ ํด๋น ํ๋กํ ํ์ ์ธ์คํด์ค์ ๋ํ ๊ธฐ๋ก์ ์ ์งํ์ง ์์ต๋๋ค.
๋ฐ๋ผ์ ์ด๊ธฐํ ์๋ช ์ฃผ๊ธฐ ์ฝ๋ฐฑ ๋ฉ์๋๋ ๋ชจ๋ ๊ฐ์ฒด์ ๋ํด ํธ์ถ๋์ง๋ง, ์๋ฉธ ์๋ช ์ฃผ๊ธฐ ์ฝ๋ฐฑ์ ํธ์ถ๋์ง ์์ต๋๋ค. ํด๋ผ์ด์ธํธ ์ฝ๋๋ ํ๋กํ ํ์ ์ค์ฝํ์ ๊ฐ์ฒด๋ฅผ ์ ๋ฆฌํ๊ณ , ํ๋กํ ํ์ Bean์ด ๋ณด์ ํ ๋น์ฉ์ด ๋ง์ด ๋๋ ๋ฆฌ์์ค๋ฅผ ํด์ ํด์ผ ํฉ๋๋ค. ํ๋กํ ํ์ ์ค์ฝํ์ Bean์ด ๋ณด์ ํ ๋ฆฌ์์ค๋ฅผ ํด์ ํ๋ ค๋ฉด, ์ฐธ์กฐ๋ฅผ ์ ์งํ๊ณ ์ ๋ฆฌํด์ผ ํ๋ Bean์ ๋ณด์ ํ๋ ์ฌ์ฉ์ ์ ์ Bean Post-Processor๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
์ด๋ค ๋ฉด์์๋ Spring ์ปจํ
์ด๋๊ฐ ํ๋กํ ํ์
์ค์ฝํ Bean์ ๋ํด ์ํํ๋ ์ญํ ์ด Java์ new
์ฐ์ฐ์๋ฅผ ๋์ฒดํ๋ ๊ฒ์
๋๋ค. ๊ทธ ์ดํ์ ๋ชจ๋ ์๋ช
์ฃผ๊ธฐ ๊ด๋ฆฌ๋ ํด๋ผ์ด์ธํธ๊ฐ ์ฒ๋ฆฌํด์ผ ํฉ๋๋ค.
Singleton Beans with Prototype-bean Dependencies
์ฑ๊ธํค ์ค์ฝํ Bean์ด ํ๋กํ ํ์ ์ค์ฝํ Bean์ ์์กด์ฑ์ ๊ฐ์ง ๋, ์์กด์ฑ์ ์ธ์คํด์คํ ์์ ์ ํด๊ฒฐ๋ฉ๋๋ค. ๋ฐ๋ผ์ ์ฑ๊ธํค Bean์ ํ๋กํ ํ์ ์ค์ฝํ Bean์ ์์กด์ฑ ์ฃผ์ ํ๋ฉด, ์๋ก์ด ํ๋กํ ํ์ Bean ์ธ์คํด์ค๊ฐ ์์ฑ๋์ด ์ฑ๊ธํค Bean์ ์ฃผ์ ๋ฉ๋๋ค. ์ด ํ๋กํ ํ์ ์ธ์คํด์ค๋ ์ฑ๊ธํค ์ค์ฝํ Bean์ ์ ๊ณต๋๋ ์ ์ผํ ์ธ์คํด์ค์ ๋๋ค.
๊ทธ๋ฌ๋ ์ฑ๊ธํค ์ค์ฝํ Bean์ด ๋ฐํ์์ ํ๋กํ ํ์ ์ค์ฝํ Bean์ ์๋ก์ด ์ธ์คํด์ค๋ฅผ ๋ฐ๋ณต์ ์ผ๋ก ํ๋ํ๋ ค๋ ๊ฒฝ์ฐ, ํ๋กํ ํ์ ์ค์ฝํ Bean์ ์ฑ๊ธํค Bean์ ์์กด์ฑ ์ฃผ์ ํ ์ ์์ต๋๋ค. ์๋ํ๋ฉด ์ด๋ฌํ ์ฃผ์ ์ Spring ์ปจํ ์ด๋๊ฐ ์ฑ๊ธํค Bean์ ์ธ์คํด์คํํ๊ณ ์์กด์ฑ์ ํด๊ฒฐํ ๋ ๋จ ํ ๋ฒ๋ง ๋ฐ์ํ๊ธฐ ๋๋ฌธ์ ๋๋ค.
Request, Session, Application, and WebSocket Scopes
request
, session
, application
, websocket
์ค์ฝํ๋ ์น ์ธ์ Spring ApplicationContext ๊ตฌํ์ฒด(XmlWebApplicationContext
๋ฑ)์์๋ง ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ด๋ฌํ ์ค์ฝํ๋ฅผ ์ผ๋ฐ Spring IoC ์ปจํ
์ด๋(ClassPathXmlApplicationContext
๋ฑ)์ ํจ๊ป ์ฌ์ฉํ๋ฉด, ์ ์ ์๋ Bean ์ค์ฝํ์ ๋ํ IllegalStateException
์ด ๋ฐ์ํฉ๋๋ค.
์ด๊ธฐ ์น ์ค์
์์ฒญ, ์ธ์ , ์ ํ๋ฆฌ์ผ์ด์ , ์น์์ผ ์์ค์์ Bean์ ์ค์ฝํ์ ์ง์ํ๊ธฐ ์ํด ์ผ๋ถ ์ด๊ธฐ ์ค์ ์ด ํ์ํฉ๋๋ค.
์ด๊ธฐ ์ค์ ๋ฐฉ๋ฒ์ ํน์ Servlet ํ๊ฒฝ์ ๋ฐ๋ผ ๋ค๋ฆ ๋๋ค.
Request Scope
๋ค์์ Bean ์ ์๋ฅผ ์์ฒญ ์ค์ฝํ๋ก ์ค์ ํ XML ๊ตฌ์ฑ ์์์ ๋๋ค:
<bean id="loginAction" class="com.something.LoginAction" scope="request"/>
Spring ์ปจํ
์ด๋๋ ๊ฐ HTTP ์์ฒญ๋ง๋ค loginAction
Bean ์ ์๋ฅผ ์ฌ์ฉํ์ฌ ์๋ก์ด LoginAction
Bean ์ธ์คํด์ค๋ฅผ ์์ฑํฉ๋๋ค. ์ฆ, loginAction
Bean์ HTTP ์์ฒญ ์์ค์์ ์ค์ฝํ๋ฉ๋๋ค.
์์ฑ๋ ์ธ์คํด์ค์ ๋ด๋ถ ์ํ๋ฅผ ๋ณ๊ฒฝํด๋, ๋์ผํ loginAction
Bean ์ ์๋ก๋ถํฐ ์์ฑ๋ ๋ค๋ฅธ ์ธ์คํด์ค๋ค์ ์ด๋ฌํ ์ํ ๋ณ๊ฒฝ์ ๋ณด์ง ๋ชปํฉ๋๋ค. ์ด๋ ๊ฐ ์ธ์คํด์ค๊ฐ ๊ฐ๋ณ ์์ฒญ์ ํนํ๋์ด ์๊ธฐ ๋๋ฌธ์
๋๋ค. ์์ฒญ ์ฒ๋ฆฌ๊ฐ ์๋ฃ๋๋ฉด, ์์ฒญ ์ค์ฝํ์ ์ํ Bean์ ํ๊ธฐ๋ฉ๋๋ค.
์ ๋
ธํ
์ด์
๊ธฐ๋ฐ ๊ตฌ์ฑ์ด๋ Java ์ค์ ์ ์ฌ์ฉํ ๋๋ @RequestScope
์ ๋
ธํ
์ด์
์ ์ฌ์ฉํ์ฌ ์ปดํฌ๋ํธ๋ฅผ ์์ฒญ ์ค์ฝํ๋ก ์ง์ ํ ์ ์์ต๋๋ค. ์์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
@RequestScope
@Component
public class LoginAction {
// ...
}
Session Scope
๋ค์์ Bean ์ ์๋ฅผ ์ธ์ ์ค์ฝํ๋ก ์ค์ ํ XML ๊ตฌ์ฑ ์์์ ๋๋ค:
<bean id="userPreferences" class="com.something.UserPreferences" scope="session"/>
Spring ์ปจํ
์ด๋๋ userPreferences
Bean ์ ์๋ฅผ ์ฌ์ฉํ์ฌ ๋จ์ผ HTTP ์ธ์
๋์ ์๋ก์ด UserPreferences
Bean ์ธ์คํด์ค๋ฅผ ์์ฑํฉ๋๋ค.
๋ค์ ๋งํด, userPreferences
Bean์ HTTP ์ธ์
์์ค์์ ์ค์ฝํ๋ฉ๋๋ค. ์์ฒญ ์ค์ฝํ์ ๋ง์ฐฌ๊ฐ์ง๋ก, ์์ฑ๋ ์ธ์คํด์ค์ ๋ด๋ถ ์ํ๋ฅผ ๋ณ๊ฒฝํด๋ ๋์ผํ userPreferences
Bean ์ ์๋ก๋ถํฐ ์์ฑ๋ ๋ค๋ฅธ ์ธ์
์ธ์คํด์ค๋ค์ ์ด๋ฌํ ์ํ ๋ณ๊ฒฝ์ ๋ณด์ง ๋ชปํฉ๋๋ค. ์ด๋ ๊ฐ ์ธ์
์ธ์คํด์ค๊ฐ ๊ฐ๋ณ ์ธ์
์ ํนํ๋์ด ์๊ธฐ ๋๋ฌธ์
๋๋ค. HTTP ์ธ์
์ด ์ต์ข
์ ์ผ๋ก ํ๊ธฐ๋๋ฉด, ํด๋น ์ธ์
์ ์ค์ฝํ๋ Bean๋ ํ๊ธฐ๋ฉ๋๋ค.
์ ๋
ธํ
์ด์
๊ธฐ๋ฐ ๊ตฌ์ฑ์ด๋ Java ์ค์ ์ ์ฌ์ฉํ ๋๋ @SessionScope
์ ๋
ธํ
์ด์
์ ์ฌ์ฉํ์ฌ ์ปดํฌ๋ํธ๋ฅผ ์ธ์
์ค์ฝํ๋ก ์ง์ ํ ์ ์์ต๋๋ค. ์์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
@SessionScope
@Component
public class UserPreferences {
// ...
}
Application Scope
๋ค์์ Bean ์ ์๋ฅผ ์ ํ๋ฆฌ์ผ์ด์ ์ค์ฝํ๋ก ์ค์ ํ XML ๊ตฌ์ฑ ์์์ ๋๋ค:
<bean id="appPreferences" class="com.something.AppPreferences" scope="application"/>
Spring ์ปจํ
์ด๋๋ appPreferences
Bean ์ ์๋ฅผ ์ฌ์ฉํ์ฌ ์ ์ฒด ์น ์ ํ๋ฆฌ์ผ์ด์
๋์ ํ๋์ AppPreferences
Bean ์ธ์คํด์ค๋ฅผ ์์ฑํฉ๋๋ค.
์ฆ, appPreferences
Bean์ ServletContext ์์ค์์ ์ค์ฝํ๋๋ฉฐ, ์ผ๋ฐ ServletContext ์์ฑ์ผ๋ก ์ ์ฅ๋ฉ๋๋ค. ์ด๋ Spring์ ์ฑ๊ธํค Bean๊ณผ ์ ์ฌํ์ง๋ง ๋ ๊ฐ์ง ์ค์ํ ์ ์์ ๋ค๋ฆ
๋๋ค
ServletContext๋น ํ๋์ ์ฑ๊ธํค์ผ๋ก, Spring ApplicationContext๋น ํ๋์ ์ฑ๊ธํค์ด ์๋๋๋ค (ํ๋์ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฌ๋ฌ ApplicationContext๊ฐ ์์ ์ ์์).
์ค์ ๋ก ServletContext ์์ฑ์ผ๋ก ๋ ธ์ถ๋์ด ๋ณด์ด๋ฏ๋ก, ์ธ๋ถ์์ ์ ๊ทผํ ์ ์์ต๋๋ค.
์ ๋
ธํ
์ด์
๊ธฐ๋ฐ ๊ตฌ์ฑ์ด๋ Java ์ค์ ์ ์ฌ์ฉํ ๋๋ @ApplicationScope
์ ๋
ธํ
์ด์
์ ์ฌ์ฉํ์ฌ ์ปดํฌ๋ํธ๋ฅผ ์ ํ๋ฆฌ์ผ์ด์
์ค์ฝํ๋ก ์ง์ ํ ์ ์์ต๋๋ค. ์์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
@ApplicationScope
@Component
public class AppPreferences {
// ...
}
WebSocket Scope
์น์์ผ ์ค์ฝํ๋ WebSocket ์ธ์ ์ ์๋ช ์ฃผ๊ธฐ์ ์ฐ๊ด๋๋ฉฐ, STOMP over WebSocket ์ ํ๋ฆฌ์ผ์ด์ ์ ์ ์ฉ๋ฉ๋๋ค.
Scoped Beans as Dependencies
Spring IoC ์ปจํ ์ด๋๋ ๊ฐ์ฒด(Bean)์ ์ธ์คํด์คํ๋ฟ๋ง ์๋๋ผ ํ๋ ฅ์(๋๋ ์์กด์ฑ)์ ์์ด์ด๋ง๋ ๊ด๋ฆฌํฉ๋๋ค.
์๋ฅผ ๋ค์ด, HTTP ์์ฒญ ์ค์ฝํ Bean์ ๋ ๊ธด ์๋ช ์ฃผ๊ธฐ(scope)๋ฅผ ๊ฐ์ง ๋ค๋ฅธ Bean์ ์ฃผ์ ํ๋ ค๋ ๊ฒฝ์ฐ, ์ค์ฝํ๋ Bean์ ๋์ฒดํ AOP ํ๋ก์๋ฅผ ์ฃผ์ ํ ์ ์์ต๋๋ค. ์ฆ, ์ค์ฝํ๋ ๊ฐ์ฒด์ ๋์ผํ ๊ณต๊ฐ ์ธํฐํ์ด์ค๋ฅผ ๋ ธ์ถํ์ง๋ง, ๊ด๋ จ ์ค์ฝํ(์: HTTP ์์ฒญ)์์ ์ค์ ํ๊ฒ ๊ฐ์ฒด๋ฅผ ๊ฒ์ํ๊ณ ๋ฉ์๋ ํธ์ถ์ ์์ํ ์ ์๋ ํ๋ก์ ๊ฐ์ฒด๋ฅผ ์ฃผ์ ํด์ผ ํฉ๋๋ค.
๋ํ, <aop:scoped-proxy/>
๋ฅผ ์ฌ์ฉํ์ฌ ์ค์ฝํ๊ฐ ์ฑ๊ธํค์ธ Bean๊ณผ ์ค์ฝํ๊ฐ ์ธ์
์ด๋ ์์ฒญ์ธ Bean ์ฌ์ด์ ํ๋ก์๋ฅผ ์ฝ์
ํ ์ ์์ต๋๋ค. ์ค์ฝํ๊ฐ ํ๋กํ ํ์
์ธ Bean์ ๊ฒฝ์ฐ, ๊ณต์ ํ๋ก์์ ๋ชจ๋ ๋ฉ์๋ ํธ์ถ์ ์๋ก์ด ํ๊ฒ ์ธ์คํด์ค๋ฅผ ์์ฑํ๊ณ ํด๋น ์ธ์คํด์ค๋ก ๋ฉ์๋ ํธ์ถ์ ์์ํ๊ฒ ๋ฉ๋๋ค.
์ค์ฝํ๋ ํ๋ก์๋ ์งง์ ์ค์ฝํ์ Bean์ ์๋ช
์ฃผ๊ธฐ ์์ ํ๊ฒ ์ ๊ทผํ๋ ์ ์ผํ ๋ฐฉ๋ฒ์ ์๋๋๋ค. ๋ํ ObjectFactory<MyTargetBean>
๋๋ ObjectProvider<MyTargetBean>
์ ์ฌ์ฉํ์ฌ ๋งค๋ฒ ํ์ํ ๋ ํ์ฌ ์ธ์คํด์ค๋ฅผ ๋์ ์ผ๋ก ๊ฐ์ ธ์ฌ ์๋ ์์ต๋๋ค. JSR-330์ Provider<MyTargetBean>
๋ ๋์ผํ ๋ชฉ์ ์ ์ํด ์ฌ์ฉ๋ฉ๋๋ค.
ํ๋ก์ ์ ํ ์ ํ
Spring ์ปจํ
์ด๋๊ฐ <aop:scoped-proxy/>
์์๋ก ํ์๋ Bean์ ๋ํด ํ๋ก์๋ฅผ ์์ฑํ ๋, ๊ธฐ๋ณธ์ ์ผ๋ก CGLIB ๊ธฐ๋ฐ์ ํด๋์ค ํ๋ก์๊ฐ ์์ฑ๋ฉ๋๋ค. CGLIB ํ๋ก์๋ ๋น๊ณต๊ฐ ๋ฉ์๋๋ฅผ ์ธํฐ์
ํธํ์ง ์์ต๋๋ค. ๋ฐ๋ผ์ ์ด๋ฌํ ํ๋ก์์์ ๋น๊ณต๊ฐ ๋ฉ์๋๋ฅผ ํธ์ถํ๋ฉด ์ค์ ์ค์ฝํ๋ ํ๊ฒ ๊ฐ์ฒด๋ก ์์๋์ง ์์ต๋๋ค.
๋์์ผ๋ก, <aop:scoped-proxy/>
์์์ proxy-target-class
์์ฑ ๊ฐ์ false
๋ก ์ค์ ํ์ฌ ํ์ค JDK ์ธํฐํ์ด์ค ๊ธฐ๋ฐ ํ๋ก์๋ฅผ ์์ฑํ๋๋ก Spring ์ปจํ
์ด๋๋ฅผ ๊ตฌ์ฑํ ์ ์์ต๋๋ค. JDK ์ธํฐํ์ด์ค ๊ธฐ๋ฐ ํ๋ก์๋ ์ถ๊ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ํ์ ์๋ค๋ ์ฅ์ ์ด ์์ง๋ง, ์ค์ฝํ๋ Bean ํด๋์ค๊ฐ ์ ์ด๋ ํ๋์ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํด์ผ ํ๋ฉฐ, ์ค์ฝํ๋ Bean์ด ์ฃผ์
๋๋ ๋ชจ๋ ํ๋ ฅ์๋ ํด๋น ์ธํฐํ์ด์ค๋ฅผ ํตํด Bean์ ์ฐธ์กฐํด์ผ ํฉ๋๋ค. ๋ค์ ์์๋ ์ธํฐํ์ด์ค ๊ธฐ๋ฐ ํ๋ก์๋ฅผ ๋ณด์ฌ์ค๋๋ค:
<!-- DefaultUserPreferences๋ UserPreferences ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํ -->
<bean id="userPreferences" class="com.stuff.DefaultUserPreferences" scope="session">
<aop:scoped-proxy proxy-target-class="false"/>
</bean>
<bean id="userManager" class="com.stuff.UserManager">
<property name="userPreferences" ref="userPreferences"/>
</bean>
Injecting Request/Session References Directly
ํฉํ ๋ฆฌ ์ค์ฝํ์ ๋์์ผ๋ก, Spring WebApplicationContext๋ HttpServletRequest
, HttpServletResponse
, HttpSession
, WebRequest
๋ฐ (JSF๊ฐ ์๋ ๊ฒฝ์ฐ) FacesContext
์ ExternalContext
๋ฅผ Spring ๊ด๋ฆฌ Bean์ ํ์
๊ธฐ๋ฐ ์๋ ์ฃผ์
์ ํตํด ์ง์ ์ฃผ์
ํ ์ ์์ต๋๋ค.
Spring์ ์ผ๋ฐ Bean๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก ์ด๋ฌํ ์์ฒญ ๋ฐ ์ธ์ ๊ฐ์ฒด์ ํ๋ก์๋ฅผ ์ฃผ์ ํ์ฌ, ์ฑ๊ธํค Bean ๋ฐ ์ง๋ ฌํ ๊ฐ๋ฅํ Bean์์๋ ์์ ํ๊ฒ ์ ๊ทผํ ์ ์๋๋ก ํฉ๋๋ค.
Creating a Custom Scope (์ฌ์ฉ์ ์ ์ ์ค์ฝํ ์์ฑ)
์ฌ์ฉ์ ์ ์ ์ค์ฝํ๋ฅผ Spring ์ปจํ
์ด๋์ ํตํฉํ๋ ค๋ฉด, org.springframework.beans.factory.config.Scope
์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํด์ผ ํฉ๋๋ค. Spring Framework ์์ฒด์์ ์ ๊ณตํ๋ Scope ๊ตฌํ์ฒด์ Scope javadoc์ ์ฐธ๊ณ ํ์ฌ ํ์ํ ๋ฉ์๋๋ฅผ ๊ตฌํํ ์ ์์ต๋๋ค.
Scope
์ธํฐํ์ด์ค๋ ์ค์ฝํ์์ ๊ฐ์ฒด๋ฅผ ๊ฐ์ ธ์ค๊ณ , ์ค์ฝํ์์ ์ ๊ฑฐํ๋ฉฐ, ํ๊ดดํ ์ ์๋ ๋ค ๊ฐ์ง ๋ฉ์๋๋ฅผ ์ ๊ณตํฉ๋๋ค.
์๋ฅผ ๋ค์ด, ์ธ์ ์ค์ฝํ ๊ตฌํ์ ์ธ์ ์ ๋ฐ์ธ๋ฉ๋ ์ธ์ ์ค์ฝํ Bean์ ๋ฐํํฉ๋๋ค. ๋ค์์ ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ ๋ฉ์๋์ ์์์ ๋๋ค:
Using a Custom Scope
์ฌ์ฉ์ ์ ์ Scope
๊ตฌํ์ฒด๋ฅผ ์์ฑํ๊ณ ํ
์คํธํ ํ, Spring ์ปจํ
์ด๋์ ๋ฑ๋กํด์ผ ํฉ๋๋ค. ๋ค์์ ์ค์ฝํ๋ฅผ ๋ฑ๋กํ๋ ์ฃผ์ ๋ฉ์๋์
๋๋ค:
beanFactory.registerScope("thread", new SimpleThreadScope());
์ ์์๋ SimpleThreadScope
๋ฅผ ๋ฑ๋กํ๋ ์์์ด๋ฉฐ, ์ฌ์ฉ์ ์ ์ ์ค์ฝํ ๊ตฌํ์ฒด๋ ๋์ผํ ๋ฐฉ์์ผ๋ก ๋ฑ๋กํ ์ ์์ต๋๋ค.
XML ์ค์ ์ ํตํด ์ฌ์ฉ์ ์ ์ ์ค์ฝํ๋ฅผ ์ ์ธ์ ์ผ๋ก ๋ฑ๋กํ ์๋ ์์ต๋๋ค. ๋ค์์ CustomScopeConfigurer
๋ฅผ ์ฌ์ฉํ ์์์
๋๋ค:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="thread">
<bean class="org.springframework.context.support.SimpleThreadScope"/>
</entry>
</map>
</property>
</bean>
<bean id="thing2" class="x.y.Thing2" scope="thread">
<property name="name" value="Rick"/>
<aop:scoped-proxy/>
</bean>
<bean id="thing1" class="x.y.Thing1">
<property name="thing2" ref="thing2"/>
</bean>
</beans>
์ ์์์์ <aop:scoped-proxy/>
๋ thing2
Bean์ด thread
์ค์ฝํ๋ฅผ ๋ฐ๋ฅด๋๋ก ํ๋ก์๋ฅผ ์์ฑํฉ๋๋ค. thing1
Bean์ thing2
Bean์ ์ฐธ์กฐํ ๋ ํ๋ก์๋ฅผ ํตํด ์ ๊ทผํ๊ฒ ๋ฉ๋๋ค.
Last updated