프로그래밍/Spring

스프링(Spring) - DI(Depedency Injection) 개념과 예제 : setter() 사용

abfc 2016. 10. 22.
반응형

예제 파일 : 

diEx.zip
다운로드

 

 

이번 포스트에서는 스프링의 핵심 기능중 하나인 DI(Dependecy Injection)에 대해 알아보고 예제를 작성해보겠습니다.

DI는 말 그대로 의존성을 주입시켜준다- 입니다. 객체를 직접 생성하는 게 아니라 외부에서 생성한 후 주입을 시켜주는 방식인데요. 예제를 보며 알아가봅시다.

 

 

일단 A라는 객체에서 B, C라는 객체를 이용할 때 두가지 방법이 있습니다. 

첫번째 방법은 A객체가 B와 C객체를 New 생성자를 통해서 직접 생성하는 방법이고, 

두번째 방법외부에서 생성 된 객체를 setter()나 생성자를 통해 사용하는 방법입니다. 

 

첫번째 방법 예제를 보시면 MainClass는 Cats를 의존하고 있고, MainClass에서 직접 Cats클래스를 생성해서 사용합니다. 

 

 

 

 

 

방법1 예제)

 

 

 

 

 

두번째 방법의 그림을 보시면 A객체에서 직접 생성하지 않고, 외부에서 생성된 객체를 setter( )혹은 생성자를 이용해서 사용합니다. 이런걸 "주입"한다고 하며 스프링에서 사용하는 방식(DI)인거죠. 스프링은 다른 객체들이 사용하고, 다른 서비스를 위해 사용할 수 있는 클래스를 컨테이너 형태로 이 기능을 제공해줍니다. A라는 객체에서 B, C객체를 사용(의존)할 때 A객체에서 직접 생성을 하는 것이 아닌 외부(IOC컨테이너)에서 생성된 B, C객체를 조립(주입)시켜 setter 혹은 생성자를 통해 사용할 수 있는거죠.

 

 

 

이번엔 첫번째 방법과 같은 내용에서 스프링의 특징을 적용(방법2)시켜 보겠습니다.

 

방법2 예제)

 

 

 방법1 예제에서는 Cats클래스에 setter와 실제 작동 하는 메서드를 작성해 주었는데 방법2 예제에서는 Cats와 MyCats로 나눠주었습니다.

 Cats에는 실제 기능을 하는 메서드를 작성, MyCats에는 필요한 필드들을 선언 후 setter를 만들어 주었고, catsNameInfo()와 catsAgeInfo() 메서드를 생성하여 직접 처리하지 않고, Cats를 클래스를 사용해서 처리하도록 해줍니다.

 

  

 

메인클래스를 보시면 방법1 처럼 직접 객체를 생성하지 않고 GenericXmlApplicationContext를 사용하여 객체(bean)을 외부에서 얻어와서 호출(사용)을 합니다. 외부는 configLocation에 담겨 있는 위치겠죠? 객체(bean)을 생성한 applicationContext.xml을 보면

 

 

 

applicationContext.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?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">
 
 
<!-- "diEx.Cats"클래스를 cats라는 id를 지정해서 객체(bean)을 생성 -->
<!-- "이 객체(bean)의 이름(id)은 cats입니다. 
        cats는 diEx패키지에 있는 Cats 클래스를 말합니다." 라고 선언 --> 
<bean id="cats" class="diEx.Cats" />
 
 
<!-- "diEx.MyCats"클래스를 myCats라는 id를 지정해서 객체(bean)을 생성 -->
<bean id="myCats" class="diEx.MyCats">
    <!-- diEx.MyCats라는 클래스에 있는 필드들의 값을 설정해줌 -->
    <property name="cats"><!-- 첫번째 property(필드) -->
        <ref bean="cats"/><!-- 이 property는 위에서 생성한 bean(객체)인 cats를 참조한다. -->
    </property>
    <property name="firstCatName" value="순덕" /><!-- MyCats의 필드의 이름과 값을 설정 -->
    <property name="secondCatName" value="나비" />
    <property name="firstCatAge" value="1" />
    <property name="secondCatAge" value="2" />
</bean>
</beans>
 
cs

 

 잘 안보이니까 소스코드를 추가할게요. applicationContext.xml 파일입니다. 이곳에서 bean(객체)를 생성해줬습니다. bean이 두 개가 설정이 되어있네요. 첫번째 bean부터 보면 유니크한 값 id는 cats, id가 cats인 bean은 'diEx패키지에 있는 Cats클래스다' 라고 설정해 주었고, 두번째 bean의 id는 myCats이고, diEx패키지에 있는 MyCats클래스다 라고 설정해주었습니다.  두번째 bean. 즉, MyCats클래스에는 필드들이 있었기때문에 값을 설정해주어야 합니다. 첫번째 필드(property)인 cats는 ref(reference) bean(bean을 참조한다.) 어떤 빈을? 바로 위에서 생성한 cats라는 빈을 참조 한다고 설정되어 있네요. diEx패키지에 있는 Cats클래스를 참조한다. 라고 보시면 되겠죠.

 나머지 필드들도 각각 필드명과 필드값을 지정해서 설정해 주었습니다. (필드명과 property name은 일치해야 합니다.)

 

 

실행결과)

 

 첫번째 방법과 두번째 방법의 차이점을 아시겠나요? 정리를 하자면, DI(의존성 주입)을 적용한 두번째 예제는 직접 객체를 생성하지 않고, 외부(applicationContext.xml)에서 객체를 생성 후 사용할 객체에 주입을 시켜주어 사용합니다. 

 만약, 첫번째 방법처럼 직접 객체를 생성했을 경우, 고양이의 정보가 아닌 강아지의 정보를 보고 싶을때 메인 클래스의 소스를 싹 고쳐야 하지만 두번째 방법을 사용한다면 설정 파일만 바꿔주면 되겠죠? 지금 예제는 소스가 짧기때문에 많이 와닿지는 않을거예요^^; 하지만 프로젝트가 커지고, 소스가 길어질때는 스프링에서 사용하는 DI가 확장성이나 유지보수에 용이하기때문에 꼭 알아두시길 바랍니다.  

 

 

이번 포스트에서 알아본 방식은 DI의 두가지 방법중 setter()에 해당합니다. 위의 그림을 보시면 setter() 혹은 생성자를 이용한다고 되어있는데요. 다음 포스트에서는 생성자를 이용해서 의존성을 주입시키는 방법에 대해 알아보겠습니다.




 



 

반응형

댓글

💲 추천 글