[Spring] 스프링 빈 범위 지정(Spring Bean Scope), 싱글턴(Singleton), 프로토타입(Prototype)

2020. 12. 17. 18:07 Spring Framework/Spring 입문 - 개념 및 핵심

스프링 빈 범위 지정(Spring Bean Scope)


스프링 빈(Spring Bean)의 범위는 2가지로 나뉜다. 싱글턴(Singleton)과 프로토타입(Prototype)이다.


싱글턴 방식은 스프링 컨테이너(Spring Container)에서 자바 어플리케이션이 특정 bean을 가져올 때 딱 하나 유일한 인스턴스만을 제공하는 방식이다. 이 방식은 bean을 설정할 때 default값이다.


그와 반대로 프로토타입은 특정 bean을 가져올 때 가져올 때마다 다른 인스턴스들을 생성해서 제공하는 방식이다.


다음은 싱글턴, 프로토타입을 xml 설정파일 상에서 어떻게 설정할 것인지를 나타낸 xml 코드다.


<프로젝트 구조>

appContext.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="gun" class="com.tutorial.spring.Gun"/>
<bean id="knife" class="com.tutorial.spring.Knife"/>

<bean id="gunPlayer" class="com.tutorial.spring.Player">
<constructor-arg ref="gun"/>
</bean>
<bean id="knifePlayer" class="com.tutorial.spring.Player" scope="prototype">
<property name="weapon" ref="knife"/>
</bean>
</beans>

bean을 설정할 때 scope 속성을 통해 bean의 범위를 명시하면 된다. scope가 쓰여져 있지 않을 때는 scope="singleton" 방식으로 동작한다. 


gunPlayer는 싱글턴 방식으로 knifePlayer는 프로토타입 방식으로 스프링 컨테이너가 bean 객체를 제공할 것이다.


다음은 이를 확인해 보는 자바 코드다. gunPlayer는 제공받을 때 마다 같은 인스턴스, knifePlayer는 다른 인스턴스를 제공받는 다는 것을 알 수 있다.


import org.springframework.context.support.GenericXmlApplicationContext;

public class Main {

public static void main(String[] args) {
String xmlConfigPath = "classpath:appContext.xml";

GenericXmlApplicationContext ctx = new GenericXmlApplicationContext(xmlConfigPath);

Player gunPlayer1 = ctx.getBean("gunPlayer", Player.class);
gunPlayer1.usePlayerWeapon();

Player gunPlayer2 = ctx.getBean("gunPlayer", Player.class);
gunPlayer2.usePlayerWeapon();

if(gunPlayer1 == gunPlayer2) { // 같은 인스턴스
System.out.println("Same Instance");
}

Player knifePlayer1 = ctx.getBean("knifePlayer", Player.class);
knifePlayer1.usePlayerWeapon();

Player knifePlayer2 = ctx.getBean("knifePlayer", Player.class);
knifePlayer2.usePlayerWeapon();

if(knifePlayer1 != knifePlayer2) { // 다른 인스턴스
System.out.println("Different Instance");
}
}
}

// 결과
Use Gun
Use Gun
Same Instance
Use Knife
Use Knife
Different Instance



출처: https://engkimbs.tistory.com/681?category=767795 [새로비]