강좌/Spring 3.0

002. 스프링을 통한 의존성 주입 - XML 파일 사용

여름나라겨울이야기 2012. 11. 19. 01:43
728x90

000 ~ 005 STS 프로젝트 파일:

의사 코드

운전자가 종합 쇼핑몰에서 타이어를 구매한다.
운전자가 종합 쇼핑몰에서 자동차를 구매한다.
운전자가 자동차에 타이어를 장착한다.

Java 로 표현 - 속성 메서드 사용

ApplicationContext context = new FileSystemXmlApplicationContext("/src/main/java/expert002/expert.xml");
Tire tire = (Tire)context.getBean("tire");
Car car = (Car)context.getBean("car");
car.setTire(tire);

자 이제 드디어 스프링을 통한 의존성 주입을 구현해 보도록 하겠습니다.
스프링을 통한 의존성 주입은 생성자를 통한 의존성 주입과 속성을 통한 의존성 주입을 모두 지원하는데 여기서는 속성을 통한 의존성 주입만을 살펴보도록 하겠습니다.

그리고 눈치 까(?)셨나요?  위의 의사코드가 생산에서 구매로 달라졌을 뿐 나머지는 바뀌지 않았다는 것을요.  Sprig 을 도입한다고 해서 기존 방식과 달라질 것은 없습니다.  또한 그 동안 저희가 작성해 왔던 Tire 관련 클래스들과 Car 클래스 역시 전혀 달라지는 부분이 없게 코딩하실 수 있습니다.
오직 Driver 클래스만 살짝 손봐주시고 Spring 설정 파일 하나만 추가해 주시면 작업 끝입니다.
믿음이 안 가신다면 기존의 클래스 다이어그램과 새로운 클래스 다이어그램을 비교해 보도록 하죠.
역시 이번에도 새로운 패키지 expert002 를 만들었습니다.


 기존 클래스 다이어그램

신규 클래스 다이어그램 

 

 

 

 


자 그럼 클래스 다이어그램의 짝꿍인 시퀀스 다이어그램을 보갰습니다. 

이상한 녀석이 하나 들어왔네요.  종합 쇼핑몰 안 파는 것 없고, 없는 것 없는 울트라 슈퍼 메가 종합 쇼핑몰... 그 이름하여 두둥~~~ SpringFramework
역시 기존의 시퀀스 다이어그램과의 비교는 필수겠죠.  기존 시퀀스 다이어그램입니다.
(왜 자꾸 이전 다이어그램과 변경되지 않은 똑같은 소스을 보여주느냐구요?  저는 친절하거든요.  절대 절대로 분량을 채우기 위함은 아닐 겁니다. 쿨럭)

기존 대비 달라진 곳이 보이시나요.  네 종합 쇼핑몰이 하나 들어온 것 외에는 달라진 부분이 없습니다.  운전자가 타이어, 자동차를 직접 생산하던 시스템에서 종합 쇼핑몰을 통해 구매하는 형태로 바꾸었네요.  현실 세계와 더욱 유사해 졌네요.  다시 한 번 강조 드리지만 객체 지향과 그 기법을 활용하는 기법들은 현실 세계 지향입니다.  여유가 되면 객체지향의 4대 원리하고 하는 추상화, 캡슐화, 다형성, 상속이 현실 세계를 어떻게 반영하고 있는지도 설명할 날이 오겠지요. 여유가 된다면... 여유가 된다.. 여유가 된... 여유가... 여유...

자 그럼 종합 쇼핑몰이 들어오면서 달라지는 코드를 살펴보죠.

Tire.java - 전혀 변한게 없습니다.(물론 기존 코드 보존을 위해 새 패키지 밑에 C&P 했다는 거 외에는..)

package expert002;

public interface Tire {
 String getBrand();
}

KoreaTire.java / AmericaTire.java - 역시 변화 없습니다.

package expert002;

public class KoreaTire implements Tire {
 public String getBrand() {
  return "코리아 타이어";
 }
}

 

package expert002;

public class AmericaTire implements Tire {
 public String getBrand() {
  return "미쿡 타이어";
 }
}

Car.java - 역시 변한게 없습니다.

package expert002;

public class Car {
 Tire tire;

 public Tire getTire() {
  return tire;
 }

 public void setTire(Tire tire) {
  this.tire = tire;
 }

 public String getTireBrand() {
  return "장착된 타이어: " + tire.getBrand();
 }
}

Driver.java - 좀 변했습니다. 기존에 생산 과정이 구매 과정으로 바뀌었고, 상품을 구매할 종합 쇼핑몰 에 대한 정보가 필요하겠죠.

package expert002;

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


public class Driver {
 public static void main(String[] args) {
  ApplicationContext context = new FileSystemXmlApplicationContext("/src/main/java/expert002/expert.xml");
  Tire tire = (Tire)context.getBean("tire");
  Car car = (Car)context.getBean("car");
  car.setTire(tire);

  System.out.println(car.getTireBrand());
 }
}

2 개의 import 문이 들어왔군요.

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

종합 쇼핑몰(Spring)에 대한 정보를 가지고 있는 패키지라고 생각해 주세요.


그리고 종합 쇼핑몰(Spring)에 대한 정보가 필요 하겠죠.  자바 코드로 아래와 같습니다.

ApplicationContext context = new FileSystemXmlApplicationContext("/src/main/java/expert002/expert.xml");


드디어 종합쇼핑몰(Spring)에서 상품에 해당하는 Tire 와 Car 를 구매하는 코드 입니다.

Tire tire = (Tire)context.getBean("tire");
Car car = (Car)context.getBean("car");

그리고 한 가지 더 필요한 것이 있는데요.  아무리 좋합 쇼핑몰(Spring)이라고 하지만 상품이 입점 되어 있어야 겠지요.  입점된 상품에 대한 내역은 어디에 숨어 있을까요.  바로 위 쪽에서 xml 파일이 전체 경로로 표시된 것이 보이시나요?

/src/main/java/expert002/expert.xml

이제 보이시죠.. ^^
그럼 expert.xml 을 살펴보겠습니다.  바로 쇼핑몰에서 구매 가능한 상품 리스트가 나열되어 있습니다.
간단하게 이런 상품 리스트를 위한 xml 파일을 만드시려면 expert002 패키지의 context menu 에서 New > Other > Spring > Spring Bean Configuration File
을 선택하고 이름만 지정해 주시면 됩니다.

위와 같은 xml 파일이 expert.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="tire" class="expert002.KoreaTire"></bean>

 <bean id="americaTire" class="expert002.AmericaTire"></bean>

 <bean id="car" class="expert002.Car"></bean>

 
</beans>

3 개의 상품을 등록했습니다.  상품을 등록할 때는 bean 이라는 태그 안에 등록하고 각각의 상품을 구분하기 위한 id 속성그 상품을 어떤 클래스를 통해 생산해야 하는지를 나타내는 class 속성이 보이네요.  별로 어렵지 않으시죠?  어려우시면 안 되는데... 그래도 어려우시면 오백원 들고 오세요.
아 숙녀분은 무료.. ^^;  여성 우대 시대 잖아요.

자 그럼 이제 선긋기 놀이를 해보도록 하겠습니다.  Driver.java 와 expert.xml 사이에 선긋기를 먼저 해보세요.  아래 제가 선을 그어 놓기는 했는데 여러분이 먼저 한 번 해 보시면 학습에 더 도움이 되겠지요.

흠흠.. 그림 그리는데 시간은 많이 걸렸는데 더 난해해 보이기도 하는군요. ㅡㅡ;

KoreaTire.java 가 id=tire 인 bean 에 연결되어 있고 다시 (Tire)context.getBean("tire") 코드와 연결이 되어 있군요.  이걸 현실 세계의 말로 풀어보자면
코리아타이어 상품이 tire 라는 이름으로 진열되어 있고, 구매(getBean)할 수 있군요.
위의 선들을 잘 살펴보시고 소화하고 배설까지 하는 것은 여러분들의 몫으로 남기겠습니다.
휘리릭.. 텨.. 텨.. 텨...

이제 expert002 패키지 밑에 Driver.java 의 context menu > Run As > Java Application 을 선택/실행해 보겠습니다. 

오호라 기존과 같은 결과이면서 다른 부분이 있네요.  INFO 관련 3 줄이 보입니다.  내부적으로 쇼핑몰(Spring) 을 구축하고 있는 과정에서 보여지는 정보입니다.

사람이 변하면 죽는다고 JUnit Test Case 도 만들도록 하겠습니다.
역시 /src/test/java/expert002 패키지 밑에 CarTest.java 를 만들고 아래 내용을 입력해 주세요.  expert001_03 패키지 밑에 있던 내용을 그대로 C&P 하시면 됩니다.  Spring 을 도입했다고 해서 굳이 테스트 코드를 바꾸실 필요는 없습니다.  물론 Spring 을 도입했으니 Spring 을 활용한 테스트 코드를 만드는 것이 정석인데 그것은 다음 강좌로 미루도록 하겠습니다.

package expert002;

import static org.junit.Assert.assertEquals;
import org.junit.Test;

public class CarTest {
 @Test
 public void 자동차_코리아타이어_장착_타이어브랜드_테스트() {
  Tire tire1 = new KoreaTire();
  Car car1 = new Car();
  car1.setTire(tire1);

  assertEquals("장착된 타이어: 코리아 타이어", car1.getTireBrand());
 }

 @Test
 public void 자동차_미쿡타이어_장착_타이어브랜드_테스트() {  
  Tire tire2 = new AmericaTire();
  Car car2 = new Car();
  car2.setTire(tire2);

  assertEquals("장착된 타이어: 미쿡 타이어", car2.getTireBrand());
 }
}

자. 이렇게 스프링을 도입함으로 말미암아 얻게 된 이점은 무엇일까요?
내 여러가지 많은 이점이 발생하게 되는데요.  그 중에서 제게 한 가지 꼽으라면 자동차의 타이어 브랜드를 바꾸고자 할 때 이제는 그 무엇도 재컴파일 없이 xml 파일만 수정하면 프로그램의 실행 결과를 바꾸어 줄 수 있다는 점을 들겠습니다.
Driver.java 의 Tire tire = (Tire)context.getBean("tire"); 부분이 타이어를 구매하는 부분인데 java 소스 어디에서도 KoreaTire.java 나 AmericaTire.java 를 지칭하는 부분이 없습니다.  바로 expert.xml 에 있습니다.  지금은 expert.xml 에 tire id 가 KoreaTire 에 맞추어져 있습니다.

<bean id="tire" class="expert002.KoreaTire"></bean>
<bean id="americaTire" class="expert002.AmericaTire"></bean>

그런데 어느 날 미쿡산 타이어로 바꾸어야 한다면 아래와 같이 xml 만 고쳐주시면 소스의 변경/재컴파일/재배포 없이 바로 해당 컴퓨터 상의 xml 의 변경만으로 적용이 된다고 하는 것이죠.

<bean id="koreaTire" class="expert002.KoreaTire"></bean>
<bean id="tire" class="expert002.AmericaTire"></bean>

바로 위 처럼 expert.xml 파일만 고쳐 주시고 Dirver.java 의 context menu > Run As > Java Application 을 선택/실행해 보세요.  미쿡 타이어로 잘 나오지요?

지금이야 소스가 있고 Eclipse 기반 STS 상에서 돌리니 별로 감흥이 없을 수 있지만 실제로 class 파일들을 배포한 환경이라면...
어떤가요? 엄청난 장점 아닌가요?

그럼 오늘은 여기서 이만.. 마라나타

반응형