Java/Spring

[Spring] 02. bean 객체 생성하기(02)

담크 2021. 6. 12. 20:52

이번에는 com.test02 패키지를 만들어봅시다.

Address.java

package com.test02;

public class Address {
	
	private String name;
	private String addr;
	private String phone;
	
	public Address() {
	}
	public Address(String name, String addr, String phone) {
		this.name = name;
		this.addr = addr;
		this.phone = phone;
	}
	@Override
	public String toString() {
		return "Address [name=" + name + ", addr=" + addr + ", phone=" + phone + "]";
	}
}

MTest.java

package com.test02;

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

public class MTest {
	
	public static void main(String[] args) {
		ApplicationContext factory = new ClassPathXmlApplicationContext("com/test02/applicationContext.xml");

		Address kim = (Address) factory.getBean("kim");
		Address lee = (Address) factory.getBean("lee");
		
		System.out.println(kim);
		System.out.println(lee);
	}
}

applicationContext.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="kim" class="com.test02.Address">
		<constructor-arg name="name" value="김범수"></constructor-arg>
		<constructor-arg name="addr" value="서울시 강남구"></constructor-arg>
		<constructor-arg name="phone" value="010-1111-1111"></constructor-arg>
	</bean>
	
	<bean id="lee" class="com.test02.Address">
		<constructor-arg name="name" value="이수"></constructor-arg>
		<constructor-arg name="addr" value="서울시 동작구"></constructor-arg>
		<constructor-arg name="phone" value="010-2222-2222"></constructor-arg>
	</bean>
</beans>

코드 실행결과

 

자 이번에는 com.test01과 조금 다른 부분이 있죠?

바로 <constructor-arg>태그에 name 속성이 있다는 것인데요 이때 들어가는 name 속성의 이름은 Address.java의 생성자에 있는 아규먼트의 '변수이름'입니다.

이 부분이 DI 유형 중에 생성자 주입을 사용한 내용입니다.

 

 

다음은 com.test03 패키지를 만들어줍니다.

Address.java

package com.test03;

public class Address {
	
	private String name;
	private String addr;
	private String phone;
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getAddr() {
		return addr;
	}
	public void setAddr(String addr) {
		this.addr = addr;
	}
	public String getPhone() {
		return phone;
	}
	public void setPhone(String phone) {
		this.phone = phone;
	}
	@Override
	public String toString() {
		return "Address [이름=" + name + ", 주소=" + addr + ", 전화번호=" + phone + "]";
	}
}

MTest.java

package com.test03;

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

public class MTest {
	
	public static void main(String[] args) {
		ApplicationContext factory = new ClassPathXmlApplicationContext("com/test03/applicationContext.xml");
		
		Address lee = (Address)factory.getBean("lee");
		Address hong = (Address)factory.getBean("hong");
		
		System.out.println(lee);
		System.out.println(hong);
	}
}

applicationContext.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="lee" class="com.test03.Address">
		<property name="name" value="이순신"></property>
		<property name="addr" value="서울시 강남구"></property>
		<property name="phone" value="010-1111-2222"></property>
	</bean>
	
	<bean id="hong" class="com.test03.Address">
		<property name="name" value="홍길동"></property>
		<property name="addr" value="경기도 남양주시"></property>
		<property name="phone" value="010-3333-4444"></property>
	</bean>
</beans>

코드 실행결과

 

이번 코드에는 생성자를 안쓰고 getter, setter를 만들어서 코딩해볼게요!

(그래서 <constructor-arg>태그 대신에 <property>라는 태그를 사용해서 객체를 만들었습니다.)

 

DI의 setter 주입유형은 setter를 호출해서 값을 넣어주는건데요 전의 코드와 비교해보자면

왼쪽이 setter를 이용한 객체생성 오른쪽이 생성자를 이용한 객체생성 부분입니다.

사진이 좀 작게나오긴 했지만 오른쪽에 생성자를 이용한 부분에서 하나가 빠지게 되면 에러가 발생하게 되지만

왼쪽에서는 한줄이 빠지더라도 setter에 들어가는 값이 없을뿐이라서

이렇게 값이 null값으로 나오고 에러가 발생하지 않는다는 차이가 있습니다.

 

 

 

**

<property>에 대해 이야기를 조금 더 해보자면

현재 com.test04에서 사용하는 <property>부분의 객체는 address 타입으로 사용되고 있는데요

MTest에서 (Address)를 지워보면 factory.getBean은 오브젝트 타입으로 리턴되는것을 볼 수 있습니다.

왜 오브젝트 타입으로 리턴될까요?

이유는 ClassPathXmlApplicationContext가 xml 파일을 읽어들이는데 그 xml에 있는 객체가 어떠한 타입인지 MTest에서는 확실히 모르기 때문에 무조건 가장 큰 오브젝트 타입으로 리턴받는것 입니다.

그렇기때문에 MTest에서 (Address)factory.getBean("lee"); 처럼 Address로 명시적 형변환해서 사용합니다.