빈 생성은 기본적으로 스프링에서는 singleton이다. singleton이라는 것은 하나의 빈의 인스턴스는 오로지 하나로 이뤄진다는 말이다.

singleton = single instance of bean

이라는 공식이라고 할 수 있겠다. 모든 의존성이 있는 오브젝트든 이 sigleton 객체를 사용하는거라고 볼 수가 있다. BeanFactory.getBean()을 호출하면 늘 같은 빈의 인스턴스를 얻어내는 것과도 같은 말이다.

singleton이라는 말은 구체적으로 Singleton Pattern을 지칭하는 거라고 볼 수 있다.
Pro Spring 에서 제공하는 예를 보자.
package com.apress.prospring.ch4;
   
public class Singleton {
   
    private static Singleton instance;         <-- 내부에서 사용할 인스턴스
   
    static {
        instance = new Singleton();            <-- 인스턴스를 얻는다.(생성자로는 얻을 수
    }                                                           없다.)
   
    public static Singleton getInstance() {  <-- 인스턴스를 외부로 노출할 인터페이스
        return instance;
    }
}

instance는 어플리케이션 전체에서 only 한개임을 보장 받는다. 하지만, 결합이라는 측면은 점점 증가한다고 볼 수 있다. 코드는 항상 인스턴스를 포함하기 위해서 Singleton class에 대해서 명시적으로 알고 있어야 한다.
실제로 Singleton pattern은 2개의 pattern으로 이뤄져 있는데, 첫째는 오브젝트의 인스턴스를 관리하는 패턴을 포함하고 있다. 둘째는 인터페이스 사용 가능성을 완전히 제거해 버리는 패턴이다.  즉, 명확한 관리도 되지만 인터페이스 사용을 허용하지 않는다는 것이다.  
대부분의 오브젝트들은 Singleton 오브젝트에 직접적으로 접근하는 Singleton 인스턴스를 필요로하기 때문에 Singleton pattern을 사용하는 것은 강제적인 구현을 변경하기가 쉽지 않다.
(어렵다... 해석이 참 어렵다...)

스프링에서는 기본적으로 Singleton 인스턴스로서 모든 빈들이 생성된다. 그리고 빈의 모든 요청을 위해서 singleton 인스턴스를 사용한다.

기본적으로 singleton이니, 설정에 의해서 non-singleton이 될 수도 있겠다. 요게 스프링의 강점이다. 멀티쓰레드 상황에서는 singleton pattern이 마땅치 않으니 대안이 있어야겠다.

Pro Spring의 예를 보자.
<bean id="nonSingleton" class="java.lang.String" singleton="false">
        <constructor-arg>
            <value>Rob Harrop</value>
        </constructor-arg>
</bean>

위에서 강조하기 위해서 붉게 칠한 부분을 보면 빈 생성시 singleton을 false로 설정하고 있다. 이렇게 하면 이 빈은 non-singleton으로 생성될 것이다.

구현 코드를 보자.
package com.apress.prospring.ch4;
   
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;
   
public class NonSingleton {
   
    public static void main(String[] args) {
   
        BeanFactory factory = new XmlBeanFactory(new FileSystemResource(
                "./ch4/src/conf/beans.xml"));
       
        String s1 = (String)factory.getBean("nonSingleton");
        String s2 = (String)factory.getBean("nonSingleton");
       
        System.out.println("Identity Equal?: " + (s1 ==s2));
        System.out.println("Value Equal:? " + s1.equals(s2));
        System.out.println(s1);
        System.out.println(s2);
    }
}

결과는 요럴 것이다.
Identity Equal?: false    <-- singleton이 false 였으므로, 완전히 똑같은 인스턴스는 아니다.
Value Equal:? true       <-- 하지만, 인스턴스의 구조는 같다.
Rob Harrop
Rob Harrop

반응형

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

Spring에서의 Hibernate  (0) 2010.05.07
Chapter 3. IoC 컨테이너 소개  (0) 2010.05.07
constructor injection vs. setter injection  (0) 2010.05.07
SpringSource dm Server 1.0 설치  (0) 2010.05.07
@AspectJ 지원  (0) 2010.05.07
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기