본문으로 바로가기

[Spring] Spring Bean Scope 종류

category Back-End/Spring 2018. 5. 16. 20:27


Spring Bean Scope

스프링에서 Bean으로 지정된 객체는 기본적으로 싱글톤 객체로 관리된다. 하지만 요구사항 과 구현기능 등의 필요에 따라서 비싱글톤이 필요한 경우도 많다. 스프링에서는 이를 명시적으로 구분하기 위해서 scope라는 키워드를 제공한다. (별도의 scope를 지정하지 않으면 스프링에서 default는 singleton 이다.)


1. The singleton scope


    스프링 IoC 컨테이너는 스프링 설정에 정의된 객체 하나를 만든다.  이 싱글 인스턴스는 싱글 빈즈 캐시에 저장이 되고, 명명된 bean에 대한 요청 및 참조는 캐시 된 객체를 반환한다.

Figure 4.2. 

<bean id="accountService" class="com.foo.DefaultAccountService"/>

<!-- 다음 설정은 위의 빈 설정과 동일하다. 즉, 스프링의 기본 스코프는 싱글톤이다.-->
<bean id="accountService" class="com.foo.DefaultAccountService" scope="singleton"/>

 

 

2. The prototype scope


  최초에 하나의 객체만 생성되어 의존성 관계의 bean에 주입 될 경우 그 생성된 하나의 객체만을 주입하는 싱글톤과는 달리 프로토타입 스코프의 bean은 의존성 관계의 bean에 주입 될 때 새로운 객체가 생성되어 주입된다.


Figure 4.3. 

 

 

<bean id="accountService" class="com.foo.DefaultAccountService" scope="prototype"/>

 

3. Singleton beans with prototype-bean dependencies


  싱글톤 bean에 프로토타입의 bean을 주입하게 될 때에는 주의해야 할 점이 있다.  

  싱글톤 스코프의 bean은 최초 한번 인스턴스화 할 때 프로토타입 스코프의 bean의 주입이 한번만 발생하게 되므로 2번 이상 실행이 될 때 프로토타입의 새로운 인스턴스가 주입되야 할 경우에는 스프링 레퍼런스의 Section 4.4.6, “Method injection”을 참고하면 된다.

 

4. Request, session, and global session scopes

 

XmlWebApplicationContext 같은​ 스프링의 ApplicationContext의 구현을 사용하는 경우 request, session, and global session 스코프에서만 사용 할 수 있다.​  ClassPathXmlApplicationContext와 같은 일반 스프링 IoC 컨테이너와 이 스코프를 같이 사용 하는 경우, 알수없는 bean 스코프라는 IllegalStateException ​이 발생하게 된다. 


Initial web configuration

 

Request, session, and global session 스코프를 지원하기 위해서는 약간의 설정이 필요하다.  하지만 스프링 웹 MVC​에서는 특별한 설정이 필요것은 아니다.  스프링의 DispatcherServlet 외부에서 처리되는 요청과 서블릿 2.5 웹 컨테이너(예 : JSF 또는 스트럿츠)​를 사용하는 경우 web.xml 에  org.springframework.web.context.request.RequestContextListener  를 등록 해야 한다.​  서블릿 3.0 이상에서는 WebApplicationInitializer 인터페이스 프로그래밍을 통해서 수행할 수 있다.

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

 

리스너 설정에 문제가 있을 경우 필터 사용을 고려하면 된다.

<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="loginAction" class="com.foo.LoginAction" scope="request"/>

loginAction bean은 모든 HTTP요청에 대해서 각각의 새로운 객체를 생성 시키고 요청이 끝나게 되면 이 bean은 삭제 된다.


loginAction 정의로 부터 생성된 각각의 인스턴스들이 그들 내부의 상태를 다른 인스턴스들이 알 수 없기 때문에 loginAction 내부의 상태값을 변경 할 수 있다.


Session scope

<bean id="userPreferences" class="com.foo.UserPreferences" scope="session"/>

하나의 세션에 userPreferences bean은 하나씩 생성된다.  request 스코프의 bean과 마찬가지로 각각의 세션 스코프의 빈들은 다른 인스턴스들의 내부 상태를 알 수 없기 때문에 userPreferences 내부의 값들을 변경 할 수 있다.

 

userPreferences의 인스턴스는 세션이 사라질때 같이 사라지게 된다. 

 

 

Global session scope

<bean id="userPreferences" class="com.foo.UserPreferences" scope="globalSession"/>

글로벌 세션 범위는 (전술) 표준 HTTP 세션 범위 유사하며, 단지 포틀릿 기반 웹 응용 프로그램의 맥락에서 적용된다. 


포틀릿 스펙은 하나의 포틀릿 웹 응용 프로그램을 구성하는 모든 포틀릿들 사이에서 공유되는 글로벌 세션의 개념을 정의한다. 


글로벌 세션 스코프에서 정의 된 콩은 글로벌 포틀릿 세션의 수명에 대한 스코프 (또는 결합)이다. 


당신이 표준 서블릿 기반의 웹 응용 프로그램을 작성하고 글로벌 세션 범위를 갖는 하나 이상의 Bean을 정의하면, 표준 HTTP 세션 범위를 사용하며, 오류가 발생하지 않는다. 



Application scope

 

Spring 컨테이너는 전체 웹 응용 프로그램에 대해 한 번 appPreferences bean 정의를 사용하여 appPreferences bean의 새 인스턴스를 만든다. 

 

즉, appPreferences 콩은 일반의 ServletContext 속성으로 저장하는 ServletContext 수준에서 범위가있다. 

 

이것은 싱글톤 bean과 다소 비슷하지만 중요한 두 가지가 다르다 

 

이것은 ​ServletContext 마다 싱글톤이지만, ​스프링 ApplicationContext ​마다는 아니고(또는 특정 웹 응용 프로그램에서 여러 가지가있을 수 있다) 실제로 노출되는 것은 ServletContext 의 속성에 따라 볼 수 있다.