Spring Bean의 개념과 Bean Scope 종류
학습목표
1. Spring Bean의 개념을 이해한다.
2. Spring Scope의 종류를 확인한다.
3. singleton, prototype scope의 개념을 이해한다.
4. 구체적인 예시를 확인한다.
Spring Bean이란
1. Spring에서 POJO(plain, old java object)를 'Beans'라고 부른다.
2. Beans는 어플리케이션의 핵심을 이루는 객체이며, Spring IoC(Inversion of Control) 컨테이너에 의해 인스턴스화, 관리, 생성된다.
3. Beans는 우리가 컨테이너에 공급하는 설정 메타데이터(xml 파일)에 의해 생성된다.
- 컨테이너는 이 메타 데이터를 통해 Bean의 생성, Bean LifeCycle, Bean Dependency(종속성) 등을 알 수 있다.
4. 어플리케이션의 객체가 지정되면, 해당 객체는 getBean() 메소드를 통해 가져올 수 있다.
Spring Bean 정의
1. 일반적으로 xml 파일에 정의한다.
2. 주요속성
2-1. class(필수) : 정규화된 자바 클래스 이름
2-2. id : bean의 고유 식별자
2-3. scope : 객체의 범위(singleton, prototype)
2-4. constructor-arg : 생성 시 생성자에 전달할 인수
2-5. property : 생성 시 bean setter에 전달할 인수
2-6. init method와 destroy method
xml based configuration file
<!-- A simple bean definition -->
<bean id=".." class="..."></bean>
<!-- A bean definition with scope -->
<bean id=".." class="..." scope="singleton"></bean>
<!-- A bean definition with property -->
<bean id=".." class="...">
<property name="message" value="Hello World!"/>
</bean>
<!-- A bean definition with initialization method -->
<bean id=".." class="..." init-method="..."></bean>
Spring Bean Scope
1. 스프링은 기본적으로 모든 bean을 singleton으로 생성하여 관리한다.
1-1. 구체적으로 어플리케이션 구동 시 JVM 안에서 스프링이 bean 마다 하나의 객체를 생성하는것을 의미한다.
1-2. 그래서 우리는 스프링을 통해서 bean을 제공받으면 언제나 주입받은 bean은 동일한 객체라는 가정하에서 개발을 한다.
2. request, session, global session의 Scope는 일반 Spring 어플리케이션이 아닌, Spring MVC Application에서만 사용된다.
ㄱ. Singleton
* 'singleton' bean은 Spring컨테이너에서 한번 생성된다.
- 컨테이너가 사라질 때 bean도 제거된다.
* 생성된 하나의 인스턴스는 single beans cache에 저장되고, 해당 bean에 대한 요청과 참조가 있으면 캐시된 객체를 반환한다.
- 즉, 하나만 생성되기 때문에 동일한 것을 참조한다.
- 기본적으로 모든 bean은 scope에 명시적으로 지정되지 않으면 singleton이다.
* xml 설정 : <bean id="..." class="..." scope="singleton"></bean>
* annotation 설정 : 대상 클래스에 @Scope("singletone")
ㄴ. Prototype
* 'prototype' bean은 모든 요청에서 새로운 객체를 생성하는 것을 의미한다.
- 즉, prototype bean은 의존성 관계의 bean에 주입될 때 새로운 객체가 생성되어 주입된다.
- 정상적인 방식으로 gc에 의해 bean이 제거된다.
* annotation 설정 : 대상 클래스에 @Scope("prototype")
***참고***
a. 싱글톤으로 적합한 객체
a-1. 상태가 없는 공유 객체 : 상태를 가지고 있지 않은 객체는 동기화 비용이 없다. 따라서 매번 이 객체를 참조하는 곳에서 새로운 객체를 생성할 이유가 없다.
a-2. 읽기용으로만 상태를 가진 공유 객체 : 1번과 유사하게 상태를 가지고 있으니 읽기 전용이므로 여전히 동기화 비용이 들지 않는다. 매 요청마다 새로운 객체 생성할 필요가 없다.
a-3. 공유가 필요한 상태를 지닌 공유 객체 : 객체 간의 반드시 공유해야 할 상태를 지닌 개체가 하나 있다면, 이경우에는 해당 상태의 쓰기를 가능한 동기화할 경우 싱글턴도 적합하다.
a-4. 쓰기가 가능한 상태를 지니면서도 사용빈도가 매우높은 객체 : 어플리케이션 안에서 정말로 사용빈도가 높다면, 쓰기 접근에 대한 동기화 비용을 감안하고서라도 싱글톤을 고려할만 하다. 이 방법은 1. 장시간에 걸쳐 매우 많은 객체가 생성될 때, 2. 해당객체가 매우 작은 양의 쓰기상태를 가지고 있을 때, 3. 객체 생성비용이 매우 클 때에 유용한선택
b. 비싱글톤으로 적합한 객체
b-1. 쓰기가 가능한 상태를 지닌 객체 : 쓰기가 가능한 상태가 많아서 동기화 비용이 객체 생성 비용보다 크다면 싱글톤으로 적합x
b-2. 상태가 노출되지 않은 객체 : 일부 제한적인 경우, 내부상태를 외부에 노출하지 않는 빈을 참조하여 다른의존객체와는 독립적으로 작업을 수행하는 의존 객체가 있다면 싱글턴보다 비싱글톤 객체를 사용하는 것이 나을 수 있다.
출처: