[Spring] 스프링 XML 설정 파일 작성 방법 정리

2021. 4. 22. 00:54 Spring Framework/Spring Core

 

[Spring] 스프링 XML 설정 파일 작성 방법 정리

📄 목차

1. 스프링 XML 설정 파일 포맷
- 기본 포맷
- 애노테이션 설정을 사용하기 위한 포맷

2. 빈(Bean) 설정 예시
- 자동 주입 설정 - autowire 속성

3. DI(Dependency Injection) 설정
- 생성자 주입
- 프로퍼티 주입
- 프로퍼티 주입 - List 타입
- 프로퍼티 주입 - Set 타입
- 프로퍼티 주입 - Map 타입
- 프로퍼티 주입 - Properties 타입

4. ApplicationContext 객체 생성
- 스프링 XML 설정 파일이 한 개인 경우
- 스프링 XML 설정 파일이 여러 개인 경우
- 스프링 XML 설정 파일이 여러 개인 경우(import 태그 사용)

 

1. 스프링 XML 설정 파일 포맷

기본 포맷

👉 빈 등록, 빈 설정을 모두 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">

</beans>

 

위와 같은 네임 스페이스와 스키마 속성을 갖는 <beans> 태그 안에 스프링 빈 설정을 작성한다.

 

애노테이션 설정을 사용하기 위한 포맷

👉 빈 등록은 XML, 빈 설정은 자바 애노테이션으로 할 경우 이 포맷을 사용한다.

 
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       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 
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <context:annotation-config/>
</beans>

 

context 네임 스페이스와 <context:annotation-config/> 코드를 추가하면 빈 설정을 XML 파일이 아닌 빈 클래스의 애노테이션을 검색해 반영한다.

 

2. 빈(Bean) 설정 예시

<bean> 태그를 이용해 빈을 정의한다.

<bean id="studentDao" class="ems.member.dao.StudentDao" />

 

<bean> 태그의 필수 속성은 class 속성 하나 뿐이다.

id는 빈의 id를 통해 참조할 경우가 있는 경우에만 설정하면 된다.

자바 코드에서 getBean()으로 빈을 가져오던지, 주입 설정에서 ref 속성으로 빈을 참조하는 경우이다.

id, class 외에는 lazy-init, scope, primary, init-method, destroy-method 속성이 있다.

 

  • id : 빈 이름(id) 설정
  • class : 빈 타입 설정
  • scope : 빈의 scope 설정. singleton/prototype
  • primary : true를 지정하여 같은 타입의 빈이 여러개 일때 우선적으로 사용할 빈 설정
  • lazy-init : true를 지정하여 빈을 사용할 때 객체가 생성되도록 설정
  • init-method : 빈 객체가 생성될때 호출할 메소드 설정
  • destroy-method : 빈 객체가 소멸될때 호출할 메소드 설정

 

자동 주입 설정 - autowire 속성

클래스의 참조 타입 필드에 한해서 autowire 속성을 사용해 자동 주입되도록 설정할 수 있다.

 

XML 설정 파일

<bean id='obj2' class='com.atoz_develop.beans.TestBean1' autowire="byName"/>

<bean id='data1' class='com.atoz_develop.beans.DataBean1'/>
<bean id='data2' class='com.atoz_develop.beans.DataBean1'/>

 

<bean>의 autowire 속성에 "byName"을 설정한다.

 

자바 코드

public class TestBean1 {

	private DataBean1 data1;
	private DataBean1 data2;
	
	public DataBean1 getData1() {
		return data1;
	}
	public void setData1(DataBean1 data1) {
		this.data1 = data1;
	}
	public DataBean1 getData2() {
		return data2;
	}
	public void setData2(DataBean1 data2) {
		this.data2 = data2;
	}
}

 

TestBean1 클래스의 빈을 생성할 때 DataBean1 타입인 필드 data1, data2에 변수명과 id가 동일한 빈이 자동으로 주입된다.

따라서 <bean>의 id 속성과 클래스의 변수명이 동일해야 하며, setter를 통해 주입되므로 setter가 필요하다.


다음으로 빈의 이름(id)가 아닌 빈의 타입을 통한 자동 주입을 알아보자.

 

XML 설정 파일

<bean id='obj3' class='com.atoz_develop.beans.TestBean2' autowire="byType"/>

<bean id='data_bean2' class='com.atoz_develop.beans.DataBean2'/>

 

<bean>의 autowire 속성에 "byType"을 설정한다.

 

자바 코드

public class TestBean2 {

	private DataBean2 data1;
	private DataBean2 data2;
	
	public DataBean2 getData1() {
		return data1;
	}
	public void setData1(DataBean2 data1) {
		this.data1 = data1;
	}
	public DataBean2 getData2() {
		return data2;
	}
	public void setData2(DataBean2 data2) {
		this.data2 = data2;
	}
}

 

TestBean2 클래스의 빈을 생성할 때 DataBean2 타입인 필드 data1, data2에 타입이 같은 빈이 자동으로 주입된다.

XML 설정에 primary 설정 없이 타입이 동일한 빈이 두 개 이상 정의되어 있으면 에러가 발생하므로 이에 주의하자.

마찬가지로 setter를 통해 주입되므로 setter가 필요하다.


생성자를 통한 자동 주입은 다음과 같이 설정한다.

 

XML 설정 파일

<bean id='data_bean2' class='com.atoz_develop.beans.DataBean2'/>
<bean id='obj5' class='com.atoz_develop.beans.TestBean3' autowire="constructor"/>

 

<bean>의 autowire 속성에 "constructor"를 설정한다.

 

자바 코드

public class TestBean3 {

	private int data1;
	private String data2;
	private DataBean2 data3;
	private DataBean2 data4;
	
	public TestBean3(DataBean2 data3, DataBean2 data4) {
		this.data3 = data3;
		this.data4 = data4;
	}
	
	public int getData1() {
		return data1;
	}
	public void setData1(int data1) {
		this.data1 = data1;
	}
	public String getData2() {
		return data2;
	}
	public void setData2(String data2) {
		this.data2 = data2;
	}
	public DataBean2 getData3() {
		return data3;
	}
	public void setData3(DataBean2 data3) {
		this.data3 = data3;
	}
	public DataBean2 getData4() {
		return data4;
	}
	public void setData4(DataBean2 data4) {
		this.data4 = data4;
	}
}

 

autowire 속성을 이용한 자동 주입은 참조 타입만 가능하므로 기본 타입 필드는 다음과 같이 직접 설정해주어야 한다.

 

XML 설정 파일

<bean id='obj7' class='com.atoz_develop.beans.TestBean3' autowire="constructor">
	<constructor-arg value='200' index='0' type='int'/>
	<constructor-arg value='문자열2' index='1'/>
</bean>

 

자바 코드

public class TestBean3 {

	private int data1;
	private String data2;
	private DataBean2 data3;
	private DataBean2 data4;
	
	public TestBean3(int data1, String data2, DataBean2 data3, DataBean2 data4) {
		this.data1 = data1;
		this.data2 = data2;
		this.data3 = data3;
		this.data4 = data4;
	}
	
	public int getData1() {
		return data1;
	}
	public void setData1(int data1) {
		this.data1 = data1;
	}
	public String getData2() {
		return data2;
	}
	public void setData2(String data2) {
		this.data2 = data2;
	}
	public DataBean2 getData3() {
		return data3;
	}
	public void setData3(DataBean2 data3) {
		this.data3 = data3;
	}
	public DataBean2 getData4() {
		return data4;
	}
	public void setData4(DataBean2 data4) {
		this.data4 = data4;
	}
}

<beans> 레벨에 default-autowire 속성을 사용해서 <bean>에 autowire 설정이 되어있지 않을 경우 기본적으로 적용할 자동 주입 방법을 설정할 수 있다.

 
<?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"
    default-autowire="byName">

 

이렇게 <beans>에 default-autowire 속성을 추가하고 사용할 자동 주입 옵션을 설정한다.

그리고 특정 빈은 자동 주입을 하지 않으려면 <bean>의 autowire 속성에 "no"를 설정하면 된다.

<bean id='obj9' class='com.atoz_develop.beans.TestBean1' autowire="no"/>

 

이 빈은 default-autowire의 영향을 받지 않게 된다.

 

3. DI(Dependency Injection) 설정

생성자 주입

XML 설정 파일

<bean id="studentDao" class="ems.member.dao.StudentDao" ></bean>

<bean id="registerService" class="ems.member.service.StudentRegisterService">
    <constructor-arg ref="studentDao" />
</bean>

 

자바 코드

public class StudentRegisterService {

	private StudentDao studentDao;
	
	public StudentRegisterService(StudentDao studentDao) {
		this.studentDao = studentDao;
	}
}

생성자가 여러 개인 경우 <constructor-arg>에 type 속성을 사용해서 어떤 생성자를 사용해서 빈 객체를 만들 것인지 구체적으로 명시할 수 있다.

지정하지 않으면 기본적으로 String 타입의 아규먼트를 갖는 생성자를 사용하게 되므로 그 외의 기본 타입을 갖는 생성자 주입 시 type을 명시하는 것이 좋다.

 

XML 설정 파일

<bean id="obj1" class="com.atoz_develop.beans.TestBean">
	<constructor-arg value="100" type="int"/>
</bean>

<bean id="obj2" class="com.atoz_develop.beans.TestBean">
	<constructor-arg value="11.11" type="double"/>
</bean>

<bean id="obj3" class="com.atoz_develop.beans.TestBean">
	<constructor-arg value="문자열" type="java.lang.String"/>
</bean>

 

자바 코드

public class TestBean {
	
	private int data1;
	private double data2;
	private String data3;

	public TestBean(int data1) {
		this.data1 = data1;
		this.data2 = 0.0;
		this.data3 = null;
	}
	
	public TestBean(double data2) {
		this.data1 = 0;
		this.data2 = data2;
		this.data3 = null;
	}
	
	public TestBean(String data3) {
		this.data1 = 0;
		this.data2 = 0.0;
		this.data3 = data3;
	}
}

자바의 new 연산자로 객체를 생성할때와 달리 스프링 DI의 생성자 주입 설정 시에는 생성자 아규먼트의 순서를 다르게 할 수 있다.

스프링이 순서를 유추하기 어려울 때는 type과 index 속성을 사용해서 순서를 구체적으로 명시한다.

 

XML 설정 파일

<bean id="obj1" class="com.atoz_develop.beans.TestBean">
	<constructor-arg value="반갑습니다" type="java.lang.String"/>
	<constructor-arg value="300" type="int"/>
	<constructor-arg value="33.33" type="double"/>
</bean>

<bean id="obj2" class="com.atoz_develop.beans.TestBean">
	<constructor-arg value="44.44" type="double" index="1"/>
	<constructor-arg value="44" type="int" index="0"/>
	<constructor-arg value="안녕하세요" type="java.lang.String" index="2"/>
</bean>

 

자바 코드

public class TestBean {
	
	private int data1;
	private double data2;
	private String data3;
	
	public TestBean(int data1, double data2, String data3) {
		this.data1 = data1;
		this.data2 = data2;
		this.data3 = data3;
	}
}

객체 주입 시  <constructor-arg>에 ref 속성을 사용하는 것 외에도 <constructor-arg> 하위에 <bean>을 사용해서 빈을 직접 정의할 수 있다.

 

XML 설정 파일

<bean id="obj" class="com.atoz_develop.beans.TestBean">
	<constructor-arg>
		<bean class="com.atoz_develop.beans.DataBean"/>
	</constructor-arg>
	<constructor-arg>
		<bean class="com.atoz_develop.beans.DataBean"/>
	</constructor-arg>
</bean>

 

자바 코드

public class TestBean {
	
	private DataBean data1;
	private DataBean data2;
	
	public TestBean(DataBean data1, DataBean data2) {
		this.data1 = data1;
		this.data2 = data2;
	}
}

 

프로퍼티 주입

XML 설정 파일

<bean id="dataBaseConnectionInfoDev" class="ems.member.DataBaseConnectionInfo">
	<property name="jdbcUrl" value="jdbc:oracle:thin:@localhost:1521:xe" />
	<property name="userId" value="scott" />
	<property name="userPw" value="tiger" />
</bean>

 

<property>의 value 속성을 사용해서 값을 설정한다.

 

자바 코드

public class DataBaseConnectionInfo {

    private String jdbcUrl;
    private String userId;
    private String userPw;

    public String getJdbcUrl() {
        return jdbcUrl;
    }

    public void setJdbcUrl(String jdbcUrl) {
        this.jdbcUrl = jdbcUrl;
    }

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public String getUserPw() {
        return userPw;
    }

    public void setUserPw(String userPw) {
        this.userPw = userPw;
    }
}

XML 설정 파일

<bean id="informationService" class="ems.member.service.EMSInformationService">
	<property name="info">
		<value>Education Management System program was developed in 2015.</value>
	</property>
</bean>

value 값이 길 경우 <property>의 하위에 <value> 태그를 사용해서 값을 설정할수도 있다.

 

자바 코드

public class EMSInformationService {

	private String info;
	
	public String getInfo() {
		return info;
	}

	public void setInfo(String info) {
		this.info = info;
	}
}

프로퍼티를 통한 객체 주입은 생성자 주입과 마찬가지로 <property> 하위에 빈을 직접 정의하거나 ref 속성을 사용해서 설정할 수 있다.

 

XML 설정 파일

<bean id="testBean" class="com.atoz_develop.beans.TestBean">
	<property name="data1">
		<bean class="com.atoz_develop.beans.DataBean"/>
	</property>
	<property name="data2" ref="data_bean"/>
</bean>

<bean id="dataBean" class="com.atoz_develop.beans.DataBean"/>

 

자바 코드

public class TestBean {

	private DataBean data1;
	private DataBean data2;

	public DataBean getData1() {
		return data1;
	}

	public void setData1(DataBean data1) {
		this.data1 = data1;
	}

	public DataBean getData2() {
		return data2;
	}

	public void setData2(DataBean data2) {
		this.data2 = data2;
	}
}

 

프로퍼티 주입 - List 타입

XML 설정 파일

<bean id="informationService" class="ems.member.service.EMSInformationService">
	<property name="developers">
		<list>
			<value>Cheney.</value>
			<value>Eloy.</value>
			<value>Jasper.</value>
			<value>Dillon.</value>
			<value>Kian.</value>
		</list>
	</property>
</bean>

List 타입은 <property>.<list> 태그를 사용한다.

 

자바 코드

public class EMSInformationService {

	private List<String> developers;

	public List<String> getDevelopers() {
		return developers;
	}

	public void setDevelopers(List<String> developers) {
		this.developers = developers;
	}
}

 

추가로 <value>에는 type 속성을 사용해서 타입을 지정할 수 있다.

<property name="list2">
	<list>
		<value type='int'>100</value>
		<value type='int'>200</value>
		<value type='int'>300</value>
	</list>
</property>

 

value가 문자열이 아니라면 type 속성으로 타입을 지정해 주는 것이 좋다.


제네릭이 Class인 List의 주입은 다음과 같이 설정한다.

 

XML 설정 파일

<bean id='dataBean' class='com.atoz_develop.beans.DataBean' scope='prototype'/>

<bean id='t1' class='com.atoz_develop.beans.TestBean'>
<property name="list3">
	<list>
		<bean class='com.atoz_develop.beans.DataBean'/>
		<bean class='com.atoz_develop.beans.DataBean'/>
		<ref bean='dataBean'/>
		<ref bean='dataBean'/>
	</list>
</property>
</bean>

<bean> 태그로 빈을 직접 설정하던지, <ref>를 사용해서 기존에 설정된 빈을 참조하도록 할 수 있다.

 

자바 코드

public class TestBean {
	
	private List<DataBean> list3;

	public List<DataBean> getList3() {
		return list3;
	}

	public void setList3(List<DataBean> list3) {
		this.list3 = list3;
	}
}

 

프로퍼티 주입 - Set 타입

XML 설정 파일

<bean id='dataBean' class='com.atoz_develop.beans.DataBean' scope='prototype'/>

<bean id='t1' class='com.atoz_develop.beans.TestBean'>
<!-- 제네릭이 String인 set -->
<property name="set1">
	<set>
		<value>문자열1</value>
		<value>문자열2</value>
		<value>문자열3</value>
		<value>문자열3</value>	<!-- Set의 특성상 주입되지 않음 -->
		<value>문자열3</value>	<!-- Set의 특성상 주입되지 않음 -->
	</set>
</property>
<!-- 제네릭이 Integer인 set -->
<property name="set2">
	<set>
		<value type='int'>100</value>
		<value type='int'>200</value>
		<value type='int'>300</value>
		<value type='int'>300</value>	<!-- Set의 특성상 주입되지 않음 -->
		<value type='int'>300</value>	<!-- Set의 특성상 주입되지 않음 -->
	</set>
</property>
<!-- 제네릭이 DataBean인 set -->
<property name="set3">
	<set>
		<bean class='com.atoz_develop.beans.DataBean'/>
		<bean class='com.atoz_develop.beans.DataBean'/>
		<ref bean="dataBean"/>
		<ref bean="dataBean"/>	<!-- Set의 특성상 주입되지 않음 -->
		<ref bean="dataBean"/>	<!-- Set의 특성상 주입되지 않음 -->
		<ref bean="dataBean"/>	<!-- Set의 특성상 주입되지 않음 -->
	</set>
</property>
</bean>

 

XML로 주입 설정을 할 때 Set 타입의 특성상 중복된 값을 넣을 수 없기 때문에 <value>의 값이 같거나 <ref>의 bean id가 동일한 경우 주입되지 않는다.

특히, <bean>의 scope 속성이 prototype인 빈을 <ref>로 설정해도 주입되지 않는다는 특징이 있기 때문에 Set 타입에 여러 개의 객체를 주입해야 할때는 <bean> 태그로 직접 주입하도록 설정해야 한다.

 

자바 코드

public class TestBean {
	
	private Set<String> set1;
	private Set<Integer> set2;
	private Set<DataBean> set3;

	public Set<String> getSet1() {
		return set1;
	}

	public void setSet1(Set<String> set1) {
		this.set1 = set1;
	}

	public Set<Integer> getSet2() {
		return set2;
	}

	public void setSet2(Set<Integer> set2) {
		this.set2 = set2;
	}

	public Set<DataBean> getSet3() {
		return set3;
	}

	public void setSet3(Set<DataBean> set3) {
		this.set3 = set3;
	}
}

 

프로퍼티 주입 - Map 타입

XML 설정 파일

<bean id="informationService" class="ems.member.service.EMSInformationService">
	<property name="administrators">
		<map>
			<entry>
				<key>
					<value>Cheney</value>
				</key>
				<value>cheney@springPjt.org</value>
			</entry>
			<entry>
				<key>
					<value>Jasper</value>
				</key>
				<value>jasper@springPjt.org</value>
			</entry>
		</map>
	</property>
</bean>

Map 타입은 <property>.<map>.<entry>를 사용한다.

 

자바 코드

public class EMSInformationService {

	private Map<String, String> administrators;

	public Map<String, String> getAdministrators() {
		return administrators;
	}

	public void setAdministrators(Map<String, String> administrators) {
		this.administrators = administrators;
	}
}

다음은 제네릭 타입이 <String, Object> 인 Map의 주입 설정 예이다.

 

XML 설정 파일

<bean id='dataBean' class='com.atoz_develop.beans.DataBean' scope='prototype'/>

<!-- map -->
<bean id='t1' class='com.atoz_develop.beans.TestBean'>
<property name="map1">
	<map>
		<entry key="a1" value='문자열'/>
		<entry key='a2' value='100' value-type='int'/>
		<entry key='a3'>
			<bean class='com.atoz_develop.beans.DataBean'/>
		</entry>
		<entry key='a4' value-ref="dataBean"/>
		<entry key='a5'>
			<list>
				<value>문자열1</value>
				<value>문자열2</value>
				<value>문자열3</value>
			</list>
		</entry>
	</map>
</property>
</bean>

<entry>의 key, value 속성으로 한 줄에 설정할수도 있다.

type을 지정하지 않으면 기본적으로 문자열로 들어가기 때문에 value-type 속성을 사용해서 타입을 지정해 주어야 한다.

위 설정은 "a1"에는 문자열을, "a2"에는 정수를, "a3", "a4"에는 DataBean 타입의 객체를 서로 다른 방법으로, "a5"에는 List 객체를 주입하는 설정이다.

 

자바 코드

public class TestBean {

	private Map<String, Object> map1;

	public Map<String, Object> getMap1() {
		return map1;
	}

	public void setMap1(Map<String, Object> map1) {
		this.map1 = map1;
	}
}

 

프로퍼티 주입 - Properties 타입

XML 설정 파일

<bean id='t1' class='com.atoz_develop.beans.TestBean'>
	<!-- property -->
	<property name="prop1">
		<props>
			<prop key="p1">문자열1</prop>
			<prop key="p2">문자열2</prop>
			<prop key="p3">문자열3</prop>
		</props>
	</property>
</bean>

 

자바 코드

public class TestBean {

	private Properties prop1;

	public Properties getProp1() {
		return prop1;
	}

	public void setProp1(Properties prop1) {
		this.prop1 = prop1;
	}
}

 

4. ApplicationContext 객체 생성

스프링 XML 설정 파일이 한 개인 경우

// GenericXmlApplicationContext 사용 - 'classpath:' prefix 필요
ApplicationContext context = new GenericXmlApplicationContext("classpath:applicationContext.xml");

// ClassPathXmlApplicationContext 사용
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

 

스프링 XML 설정 파일이 여러 개인 경우

String[] appCtxs = {"classpath:appCtx1.xml", "classpath:appCtx2.xml", "classpath:appCtx3.xml"};
ApplicationContext context = new GenericXmlApplicationContext(appCtxs);

ApplicationContext context = new ClassPathXmlApplicationContext("appCtx1.xml", "appCtx2.xml", "appCtx3.xml");

 

스프링 XML 설정 파일이 여러 개인 경우(import 태그 사용)

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">

    <import resource="classpath:appCtx2.xml"/>
    <import resource="classpath:appCtx3.xml"/>
</beans>

 

ApplicationContext 객체 생성은 XML 설정 파일이 한 개인 경우와 동일하다.

 

관련 글

[Spring] 스프링 XML 설정 → 애노테이션 설정 변환 방법

 

출처 : atoz-develop.tistory.com/entry/Spring-%EC%8A%A4%ED%94%84%EB%A7%81-XML-%EC%84%A4%EC%A0%95-%ED%8C%8C%EC%9D%BC-%EC%9E%91%EC%84%B1-%EB%B0%A9%EB%B2%95-%EC%A0%95%EB%A6%AC?category=869243