반응형

Spring - Bean Scopes


(원문 위치 : http://www.tutorialspoint.com/spring/spring_bean_scopes.htm )

Spring에서 <bean>을 선언할때, 그 bean의 범위(scope) 선언의 옵션을 정할 수 있다. 예를들면, 요청되는 매번 새로운 bean instance를 만들도록 하기위하여 bean 속성에 'prototype'을 선언할 수 있다. 유사하게 요청되는 매번 동일한 bean이 반환되도록 하려면 bean의 속성에 'singleton'을 선언한다.

Spring framework는 다섯가지 범위(scope)를 지원하지만, 이중 셋은 오로지 web-aware ApplicationContext를 사용해야만 사용 가능하다(아직 나머지 셋에 대한 강좌를 못찾았다. 찾으면 추후 포스팅할 예정임).
ScopeDescription
singleton

default 속성. bean 정의가 Spring IoC container당 single instance의 범위를 지정. 

prototype하나의 bean정의가 다수의 객체 instance를 갖는 범위를 지정.
request

Bean정의가 HTTP request 범위로 지정. 

오직 web-aware Spring ApplicationContext에서만 유효.

session

Bean정의가 HTTP session 범위로 지정. 

오직 web-aware Spring ApplicationContext에서만 유효.

global-sessionBean정의가 global HTTP session 범위로 지정. 

오직 web-aware Spring ApplicationContext에서만 유효.

The singleton scope:

Scope가 singleton으로 설정되면, Sprin IoC container는 해당 bean 정의에 따라 정확하게 하나의 instance만을 생성한다. Single instance는 singleton bean같이 캐시에 저정되어지며 해당 bean에 대한 모든 연이은 요청(request)과 참조(reference)는 캐쉬되어진 객체에서 반환된다.

Default scope는 항상 singleton이지만, 하나의 요청과 오로지 하나의 bean instance를 원하면, 아래와 같이 bean 설정에서 scope 속성에 'singletone'을 설정할 수 있다.
<!-- A bean definition with singleton scope -->
<bean id="..." class="..." scope="singleton">
    <!-- collaborators and configuration for this bean go here -->
</bean>

Example:

[003] HelloWorld Example을 참조하여 프로젝트를 생성.
    - package : com.tutorialspoint
    - project : 004.SpringExample

HelloWorld.java:

package com.tutorialspoint;

public class HelloWorld {
   private String message;

   public void setMessage(String message){
      this.message  = message;
   }

   public void getMessage(){
      System.out.println("Your Message : " + message);
   }
}

MainApp.java: 실제로 하나의 객체가 반환되는지 확인을 위해 HelloWorld를 두번 생성하여 진행한 것을 제외하면 커다란 변화는 없다.

package com.tutorialspoint;

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

public class MainApp {
   public static void main(String[] args) {
      ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");

      HelloWorld objA = (HelloWorld) context.getBean("helloWorld");

      objA.setMessage("I'm object A");
      objA.getMessage();

      HelloWorld objB = (HelloWorld) context.getBean("helloWorld");
      objB.getMessage();
   }
}

Beans.xml: scope를 'singleton'으로 설정한 부분을 잘 보자.

<?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-3.0.xsd">

   <bean id="helloWorld" class="com.tutorialspoint.HelloWorld" 
      scope="singleton">
   </bean>

</beans>

결과는 아래와 같다. 결과에서 보이듯 objA에서 설정한 String이 objB에서 그대로 출력되고 있음을 알 수 있다.

Your Message : I'm object A
Your Message : I'm object A

The prototype scope:

Scope가 'prototype'으로 설정되면, Spring IoC Container는 매 요청시마다 해당 bean의 새로운 instance를 생성한다. 보통 state-full(stateful) bean에 대해 prototype을 사용하고 singleton scope는 stateless bean에 대해 사용하라. (어렵게 생각하지 말자. state-full(stageful)은 TCP socket같이 이전 정보를 알 수 있는 녀석이고 stateless는 HTTP같이 이전 정보를 모르고 움직이는 녀석이라고 편하게 생각하자. - 궁금해서 찾아보는건 말리지는 않는다.)

'prototype' scope를 정의하기 위해서는 scope 속성에 'prototype'을 아래와 같이 설정하면 된다.
<!-- A bean definition with singleton scope -->
<bean id="..." class="..." scope="prototype">
   <!-- collaborators and configuration for this bean go here -->
</bean>

Example:

[003] HelloWorld Example을 참조하여 프로젝트를 생성.
    - package : com.tutorialspoint
    - project : 005.SpringExample

HelloWorld.java: 변한것 없음.

package com.tutorialspoint;

public class HelloWorld {
   private String message;

   public void setMessage(String message){
      this.message  = message;
   }

   public void getMessage(){
      System.out.println("Your Message : " + message);
   }
}

MainApp.java: 'singleton' 예제와 완전히 동일함.

package com.tutorialspoint;

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

public class MainApp {
   public static void main(String[] args) {
      ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");

      HelloWorld objA = (HelloWorld) context.getBean("helloWorld");

      objA.setMessage("I'm object A");
      objA.getMessage();

      HelloWorld objB = (HelloWorld) context.getBean("helloWorld");
      objB.getMessage();
   }
}

Beans.xml: scope가 'prototype'인 것을 제외하고 완전히 동일함.

<?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-3.0.xsd">

   <bean id="helloWorld" class="com.tutorialspoint.HelloWorld" 
      scope="prototype">
   </bean>

</beans>

결과는 아래와 같으며, 이번에는 'singleton'과는 다르게 objB의 결과가 'null'로 출력됨을 알 수 있다.

Your Message : I'm object A
Your Message : null


반응형

+ Recent posts