본문 바로가기

Programming/Spring

Spring - Bean Scope

Bean Scope

Bean의 정의는 실제 bean 객체를 생성하는 방식을 정의하는 것이다.

Class와 마찬가지로 하나의 Bean 정의에 해당하는 다수의 객체가 생성될 수 있다.

Bean 정의를 통해 객체에 다양한 종속성 및 설정값을 주입할 수 있을 뿐 아니라, 객체의 범위(scope)를 정의할 수 있다. Spring Framework는 5가지 scope을 제공한다.

(그 중 3가지는 web-aware ApplicationContext를 사용할 때 이용할 수 있다).

 

 Scope

 설명

 singleton

 하나의 Bean 정의에 대하여 Spring IoC Container 내에 단 하나의 객체만 존재

 prototype

 하나의 Bean 정의에 대하여 다수의 객체가 존재 할 수 있다.

 request

 하나의 Bean 정의에 대하여 하나의 HTTP request의 생명주기 안에 단 하나의 객체만 존재

 즉, 각각의 HTTP Request는 자신만의 객체를 가진다.

 Web-aware String ApplicaiontContext 안에서만 유효하다.

 session

 하나의 Bean 정의에 대해서 하나의 HTTP Session의 생명주기 안에 단 하나의 객체만 존재

 Web-aware String ApplicaiontContext 안에서만 유효하다.

 global

 session

 하나의 Bean 정의에 대하여 하나의 global HTTP Session의 생명주기 안에 단 하나의 객체

 일반적으로 portlet context 안에서 유효하다

 Web-aware String ApplicaiontContext 안에서만 유효하다.

 

 

[ Singleton Scope ]

Bean이 singleton인 경우, 단지 하나의 공유 객체만 관리된다. Singleton은 Spring의 기본 scope이다.

Singleton은 객체가 하나만 생성되는 싱글톤 객체에 DI를 하게되면 DI 된 객체도 한 번 밖에 세팅되지 않기 때문에Dependency Injection (이후 DI)을 사용할 수 없다.

<bean id="beanTest" class="test.BeanTest" /> // default가 singleton이기에 생략 가능
<bean id="beanTest" class="test.BeanTest" scope="singleton"/>
<bean id="beanTest" class="test.BeanTest" singleton="true"/>

 

Singleton Scope의 간단한 예제

BeanTest.java

package test;
public class BeanTest {    
    public BeanTest(){}
}


ExamMain.java

package test.;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

public class ExamMain {
    public static void main(String[] args) {
        ApplicationContext context = new FileSystemXmlApplicationContext("/src/test/exam06.xml");
        BeanTest beanTest1 = (BeanTest)context.getBean("beanTest");
        BeanTest beanTest2 = (BeanTest)context.getBean("beanTest");
        BeanTest beanTest3 = (BeanTest)context.getBean("beanTest");
  
        System.out.println("beanTest1 : " + beanTest1);
        System.out.println("beanTest2 : " + beanTest2);
        System.out.println("beanTest3 : " + beanTest3);
    }
}

 

exam06.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">

    <bean id="beanTest" class="test.BeanTest" scope="singleton" />
</beans>

 

결과 화면

 

위 소스의, exam06.xml 설정 파일을 보면 빈을 생성할 때 scope="singleton" 속성으로 지정되어 있다.

Singleton으로 생성되어 있기 때문에 getBean()으로 각각 호출한 beanTest1~3이 모두 동일한 빈 객체를 참조하고 있음을 알수 있다.

 

 

Singleton 패턴과 스프링의 Singleton 차이

http://toby.epril.com/?p=849 <= 참조 (깔끔하게 정리를 하고 싶은데,,,정리가 안된다,,,;;)

 

 

[ Prototype Scope ]

Singleton이 아닌 prototype scope의 형태로 정의된 bean은 필요한 매 순간 새로운 bean 객체가 생성된다

<bean id="beanTest" class="test.BeanTest" scope="prototype"/>

<bean id="beanTest" class="test.BeanTest" singleton="false"/>

 

Prototype scope을 사용할 때 염두에 두고 있어야 할 것이 있다.

Spring은 prototype bean의 전체 생명주기를 관리하지 않는다 - container는 객체화하고, 값을 설정하고, 다른 prototype 객체와 조립하여 Client에게 전달 한 후 더 이상 prototype 객체를 관리하지 않는다.

즉, scope에 관계없이 초기화(initialization) 생명주기 callback 메소드가 호출되는 반면에, prototype의 경우 파괴(destruction) 생명주기 callback 메소드는 호출되지 않는다. 이것은 client 코드가 prototype 객체를 clean up하고 prototype 객체가 들고 있던 리소스를 해제하는 책임을 가진다는 것을 의미한다.

 

Prototype Scope의 간단한 예제

exam06.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">

    <bean id="beanTest" class="test.BeanTest" scope="prototype" />
</beans>

 

결과화면

 

위의 scope속성을 위와 같이 prototype으로 수정해주면 빈을 사용할 때마다 빈을 새로 생성하기 때문에 서로 다른 객체를 참조하고 있음을 알 수 있다.

 

 

 

[ 기타 Scope ]

request, session, global session scope들은 반드시 web-based 어플리케이션에서 사용할 수 있다.

기본 Web 설정(Initial web configuration)
request, session, global session scope을 사용하기 위해서는 추가적인 설정이 필요하다.

 

추가 설정은 사용할 Servlet 환경에 따라 달라진다.만약 Spring Web MVC 안에서 bean에 접근할 경우, 즉 Spring DispatcherServlet 또는 DispatcherPortlet에서 처리되는 요청인 경우, 별도의 추가 설정은 필요없다.

DispatcherServletDispatcherPortlet은 이미 모든 관련있는 상태를 제공한다.

 

만약 Servlet 2.4+ web container를 사용하고, JSF나 Struts 등과 같이 Spring의 DispatcherServlet의 외부에서 요청을 처리하는 경우, 다음 javax.servlet.ServletRequestListener'web.xml' 파일에 추가해야 한다.

<web-app>
     ...
    <listener>
        <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
    </listener>
    ...
</web-app>

 

만약 다른 오래된 web container(Servlet 2.3)를 사용한다면, 제공되는 javax.servlet.Filter 구현체를 사용해야 한다. (filter mapping은 web 어플리케이션 설정에 따라 달라질 수 있으므로, 적절히 수정해야 한다.)

<web-app>
    ...
    <filter>
        <filter-name>requestContextFilter</filter-name> 
        <filter-class>org.springframework.web.filter.RequestContextFilter</filter-class>
    </filter>
    <filter-mapping> 
        <filter-name>requestContextFilter</filter-name> 
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    ...
</web-app>

 

 

Request scope

<bean id="beanTest" class="test.BeanTest" scope="request"/>

 

위 정의에 따라, Spring container는 모든 HTTP request에 대해서 'loginAction' bean 정의에 대한 LoginAction 객체를 생성할 것이다. 즉, 'loginAction' beanHTTP request 수준에 한정된다(scoped). 요청에 대한 처리가 완료되었을 때, 한정된(scoped) bean도 폐기된다.

 

 

session scope

<bean id="beanTest" class="test.BeanTest" scope="session"/>

 

위 정의에 따라, Spring container는 하나의 HTTP Session 일생동안 'userPreferences' bean 정의에 대한 UserPreferences 객체를 생성할 것이다. 즉, 'userPreferences' beanHTTP Session 수준에 한정된다(scoped). HTTP Session이 폐기될 때, 한정된(scoped) bean로 폐기된다

 

 

global session scope

<bean id="beanTest" class="test.BeanTest" scope="globalSession"/>

 

global session scope은 HTTP Session scope과 비슷하지만 단지 portlet-based web 어플리케이션에서만 사용할 수 있다. Portlet 명세(specifications)는 global Session을 하나의 portlet web 어플리케이션을 구성하는 여러 portlet들 모두가 공유하는 것으로 정의하고 있다. global session scope으로 설정된 bean은 global portlet Session의 일생에 한정된다

 

 

 

 

 

참조목록

http://snoopy81.tistory.com/170

http://openframework.or.kr/framework_reference/spring/ver2.x/html/beans.html

http://www.egovframe.org/wiki/doku.php?id=egovframework:rte:fdl:ioc_container:bean_scope

'Programming > Spring' 카테고리의 다른 글

Spring - POJO  (2) 2012.05.14
Spring - Bean 초기화 및 생명주기  (0) 2012.05.11
Spring - IoC & DI  (0) 2012.05.09
Spring - AOP 개념 정리  (6) 2012.05.08
Spring MVC 와 DispatcherServlet  (0) 2012.05.07