관리 메뉴

거니의 velog

(3) 스프링 의존성 주입과 제어 역전 기능 2 본문

Java_Spring Framework part1

(3) 스프링 의존성 주입과 제어 역전 기능 2

Unlimited00 2023. 10. 2. 20:48

2. 의존성 주입 실습하기

* 이번에는 의존성 주입의 두 방법인 setter를 이용한 방식과 생성자를 이용한 방식을 각각 실습을 통해 확인해 보자. 먼저 setter를 이용해 DI를 실습하는 방식부터 알아보자.


(1) setter를 이용한 DI 기능

* 다음 그림은 setter를 이용해 실습할 클래스들의 계층 구조이다.

클래스 계층 구조

* 자바 프로젝트에서 DI 기능을 실습하려면 우선 스프링 관련 라이브러리의 패스를 설정해 주어야 한다.

1. 이클립스 상단에서 New > Project... 를 선택한 후 Java Project를 선택하고 Next를 클릭한다.

2. 프로젝트 이름으로 pro19를 입력하고 Finish를 클릭한다.

3. 이클립스에서 자바 프로젝트를 생성한다. 자바 프로젝트 생성 시 이클립스의 Perspective를 자바 모드로 변경할지 물으면 Remember My decision 체크박스에 체크하고 Open Perspective를 클릭한다.

4. Project Explorer에서 자바 프로젝트가 생성된 것을 확인할 수 있다.

5. 프로젝트 pro19 아래 새 폴더 lib를 만든 후 스프링 DI 관련 라이브러리를 복사해 붙여 넣는다.

6. pro19를 선택하고 마우스 오른쪽 버튼을 클릭한 후 Build Path > Configure Build Path...를 선택한다.

7. Libraried 탭에서 Classpath 를 선택하고 Add JARs... 를 클릭한다.

8. 앞에서 미리 만든 lib 폴더의 라이브러리들을 모두 선택한 후 OK를 클릭한다.

9. Apply and Close를 클릭하여 이 내용을 적용한다.

10. Project Explorer의 Referenced Libraries에서 jar 파일들을 확인할 수 있다.

11. 이제 DI 설정을 할 차례이다. 스프링에서 DI 설정은 XML 파일에서 한다. 따라서 빈을 설정하는 person.xml 파일을 생성해야 한다. pro19 위에서 마우스 오른쪽 버튼을 클릭한 후 New > Other...를 선택하고 선택 창에서 XML > XML File을 선택하고 Next를 클릭한다.

12. 파일 이름으로 person.xml을 입력하고 Finish를 클릭한다.

13. 프로젝트 이름 하위에 person.xml이 생성된 것을 확인할 수 있다.

* 다음은 XML 파일에서 빈을 생성하는 데 사용되는 <bean> 태그의 속성들을 살펴보자. 다음 표는 <bean> 태그에 사용되는 여러 속성들을 정리했다.

< <bean> 태그에 사용되는 여러 가지 속성들 >

속성 이름 설명
id 빈 객체의 고유 이름으로, 빈 id를 이용해 빈에 접근한다.
name 객체의 별칭이다.
class 생성할 클래스이다. 패키지 이름까지 입력해야 한다.
constructor-arg 생성자를 이용해 값을 주입할 때 사용한다.
property setter를 이용해 값을 주입할 때 사용한다.

14. 다음과 같이 person.xml을 작성한다. <beans> 태그로 스프링 실행 시 생성할 빈을 설정한다. 빈은 앞에서도 언급했듯이 스프링을 실행할 때 사용하는 클래스 객체(인스턴스)이다.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>

	<!-- <bean>태그를 이용해 PersonServiceImpl 객체(빈)를 생성한 후 빈 id를 personService로 지정한다. -->
	<bean id="personService" class="com.spring.ex01.PersonServiceImpl">
		<!-- PersonServiceImpl 객체의 속성 name 값을 <value> 태그를 이용해 '홍길동'으로 초기화한다. -->
	   <property name="name">
	      <value>홍길동</value>
	   </property>
	</bean>
	
	<bean id="personService1" class="com.spring.ex02.PersonServiceImpl">
	     <constructor-arg   value="이순신" />
	</bean>
	
	<bean id="personService2" class="com.spring.ex02.PersonServiceImpl">
	    <constructor-arg   value="손흥민"  />
	    <constructor-arg   value="23"  />
	</bean>

</beans>

* 위 코드처럼 실행 클래스 실행 시 <bean> 태그를 이용해 com.spring.ex02.PersonServiceImpl 클래스에 대한 빈을 생성한다. 그리고 이 빈에 대해 접근할 수 있는 빈 id를 personService로 지정한 후 <property> 태그를 이용해 PersonServiceImpl 클래스 객체의 name 속성에 <value> 태그의 값으로 초기화한다. 소스 코드에서 new를 이용해 직접 객체를 생성하던 것을 person.xml에서 설정한 것이다.

15. 이번에는 실습 관련 클래스를 구현할 차례이다. com.spring.ex01 패키지를 만들고 클래스 파일을 생성한다.

16. PersonService 인터페이스를 다음과 같이 작성한다. 인터페이스 PersonService에 추상 메서드 sayHello()를 선언한다.

package com.spring.ex01;

public interface PersonService {
	public void sayHello();
}

17. PersonServiceImpl 클래스를 다음과 같이 작성한다. 구현 클래스 PersonServiceImpl에서 인터페이스 PersonService를 구현하고 setter를 이용해 person.xml에서 <value> 태그로 설정한 값을 name 속성에 주입한다. 단, age 속성은 setter가 없으므로 빈이 생성되더라도 값이 초기화되지 않는다.

package com.spring.ex01;

public class PersonServiceImpl implements PersonService {
	
	private String name;
	private int age;

	public void setName(String name) { // <value> 태그의 값을 setter를 이용해 설정한다.
		this.name = name;
	}

	@Override
	public void sayHello() {
		System.out.println("이름: " + name);
		System.out.println("나이: " + age);
	}
	
}

18. 다음과 같이 실행 클래스인 PersonTest 클래스를 작성한다. 라이브러리에서 제공하는 클래스를 이용해 XML 파일을 읽어와서 빈을 생성해 사용한다. 실행 클래스를 실행하면 스프링의 XmlBeanFactory 클래스를 이용해 person.xml의 설정대로 PersonServiceImpl 빈을 메모리에 생성한다. 이 빈에 대한 id인 personService로 접근하여 sayHello() 메서드를 호출한다.

package com.spring.ex01;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;

public class PersonTest {

	public static void main(String[] args) {
		BeanFactory factory = new XmlBeanFactory(new FileSystemResource("person.xml")); // 실행 시 person.xml을 읽어 들여 빈을 생성한다.
		PersonService person = (PersonService) factory.getBean("personService"); // id가 personService인 빈을 가져온다.
		// PersonService person = new PersonServiceImpl(); // 더 이상 자바 코드에서 객체를 직접 생성하지 않아도 되므로 주석 처리한다.
		person.sayHello(); // 생성된 빈을 이용해 name 값을 출력한다.
	}

}

19. main() 메서드가 있는 실행 클래스(PersonTest.java)가 보이는 상태에서 이클립스 상단의 녹색 아이콘을 클릭해 자바 프로젝트를 실행한다.

20. 콘솔에 name 속성 값은 person.xml에서 <value> 태그로 설정한 값이 출력되지만 age 속성 값은 0이 출력된다.