DI(Dependency Injection - 의존성 주입)

  • 의존성 : 클래스의 객체가 다른 클래스의 객체에서 사용되는 것
  • 주입 : 클래스 안에서 사용하는 객체를 내부에서 만들지 않고 외부에서 만든 것을 대입 받는 것
    • 주입을 받는 방법은 생성자에서 받는 방법이 있고 setter를 이용해서 주입받는 방법이 있다.
    • spring에서의 di는 생성자나 setter를 이용해서 직접 받는 것이 아니고 설정파일을 이용해서 주입받는 것

외부에서 인스턴스를 만든 후 대입하는 구조를 의존성 주입

1.Spring에서의 의존성 주입

  • 생성자(Constructor)를 이용한 주입
  • 프로퍼티(property - setter)를 이용한 주입

2.생성자를 이용한 주입

<bean class="클래스 경로" id="bean의 id">
    <constructor-arg value="값"/>
</bean>
  • constructor의 매개변수가 여러 개인 경우에는 index 속성을 이용해서 인덱스(순서)를 설정

3.생성자를 이용한 의존성 주입을 위한 실습

1) 프로퍼티 1개를 갖는 클래스를 생성

  • 프로퍼티(property) : 변수와 접근자 메소드를 모두 가진 것.
    • 접근자 메소드 없이 변수만 존재하는 경우 멤버 변수
public class DTO {
    private String name;

    public DTO() {
        super();
    }

    public DTO(String name) {
        super();
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

2) main/src -> src/main/resources 디렉토리에 Spring Bean Configuration 파일을 생성

  • diconfig.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-2.0.xsd">

    <!-- di패키지의 DTO 라는 클래스의 객체를 생성해주는 bean  -->
    <!--  DTO dto = new DTO("생성자를 이용한 주입");와 비슷 -->
    <!--  직접 작성한 코드는 호출한 횟수만큼 객체를 생성하지만 여기서는 1번만 생성  -->
    <!--  Class 경로, 생성자의 매개변수 , 프로퍼티 이름을 잘못사용하면 에러 표시 -->
    <bean id="dto" class="di.DTO">
        <constructor-arg value="생성자를 이용한 주입"/>
    </bean>
</beans>

3) di 패키지에 main 메소드를 소유한 클래스를 만들고 앞에서 만든 bean 가져다 사용하기

경로 설정에 주의 하자 ("classpath:di/diconfig.xml");
class 설정에 주의하자 DTO dto = context.getBean("dto", DTO.class);

public class DiMain {

    public static void main(String[] args) {
        // 스프링 설정 파일의 경로 설정
        // classpath : src 또는 src/main/java, src/main/resources
        GenericXmlApplicationContext context = new GenericXmlApplicationContext("classpath:di/diconfig.xml");
        // bean 찾아오기
        // 주입 받는 코드가 없음
        DTO dto = context.getBean("dto", DTO.class);
        // diconfig.xml 파일에 설정한 내용이 출력
        System.out.println(dto);

        context.close();
    }
}

4.proterty를 이용한 주입

<bean id="아이디" class="클래스경로">
    <property name="프로퍼티이름" value="값"/>
</bean>
  • property가 여러개 이면 property 태그를 추가해서 해결
  • property 태그의 name에 설정하는 것은 변수명이 아니고 setter 메소드에서 set을 제외한 부분의 첫 글자만 소문자로 변경한 것.

어느 언어에서든지 property라고 부를 때는 변수명이 아니고 getter 나 setter 메소드에서 get과 set을 제외한 부분의 첫글자만 소문자로 변경한 것 입니다.

1) diconfig.xml 파일에 프로퍼티를 이용한 주입 코드를 작성

<bean id="dto1" class="di.DTO">
        <property name="name" value="프로퍼티를 이용한 주입"/>
</bean>

2) main 메소드에 추가

        DTO dto1 = context.getBean("dto1", DTO.class);
        System.out.println(dto1.getName());

5. 다른 bean을 주입

  • value는 직접 값을 설정하는 형식
  • 이미 만들어진 다른 bean을 주입하는 것이 가능하다.
<constructor-arg>
    <ref bean="다른bean의 id"/>
</constructor-arg>
<property name="프로퍼티이름">
    <ref baen="다른bean의 id"/>
</property>

1) diconfig.xml 파일에 추가

    <bean id="string" class="java.lang.String">
        <constructor-arg value="다른bean을 이용한 주입" />
    </bean>

    <bean id="dto2" class="di.DTO">
        <!--  name 프로퍼티에 string이라는 bean을 대입 -->
        <property name="name">
            <ref bean="string" />
        </property>
    </bean>

2) main 메소드에서 확인

    DTO dto2 = context.getBean("dto2", DTO.class);
        System.out.println(dto2.getName());

6.Maven Project를 만들고 이전 실행이 잘 되었는데 git hub에 업로드 한 후 제대로 실행이 안되면 프로젝트를 선택하고 마우스 오른쪽을 클릭한 후 [Maven] - [Update Project]를 한 후 실행

7.c 와 p 네임스페이스를 이용하는 방법

1) c 네임스페이스를 설정파일에 추가하면 생성자를 이용한 주입을 bean 태그의 속성으로 가능

  • c:이름=값을 추가하는 것이 가능

2) p 네임스페이스를 추가하면 프로퍼티를 이용한 쥡을 bean 태그의 속성으로 가능

  • p:이름=값
  • p:이름-ref="다른bean의 아이디"
    <!-- p namespace를 추가해서 프로퍼티를 이용한 주입  -->
    <bean id="dto3" class="di.DTO" p:name-ref="string"/>

8.집단 자료형의 주입

  • list, set, map, properties

1) List 타입의 데이터를 주입하고자 하는 경우

<list value-type="자료형">
    <value></value>
    <value></value>
    ...
</list>
  • value-type을 생략하면 자료형을 유추합니다.
  • 다른 bean의 참조를 대입할 때는 <value> 대신에 <ref bean="bean의 id"/>

배열과 List의 차이
배열은 크기가 고정, 중간에 데이터를 삽입하거나 삭제를 할려면 배열을 복사해두고 작업, 메모리 낭비가 없음
List는 크기 변경 가능, 여분의 메모리를 가지고 있어야 하므로 메모리 낭비가 발생

2) Map

  • key 와 value를 쌍으로 저장하는 자료구조
<map>
    <entry>
        <key>key의 값</key>
        <value>value의 값</value>    
  </entry>
</map>
...

3) Properties

  • key와 value를 쌍으로 저장하는 자료구조
  • Map과 다른점은 Map은 key와 value에 모든 자료형이 가능하지만 Properties는 key와 value에 java.lang.String만 된다.
<props>
    <prop key="key의 값">value</prop>
</props>

4) Set

  • 데이터를 중복없이 순서와 상관없이 저장
  • 설정방법은 list와 동일한데 태그의 이름만 set으로 설정

9.XML 설정과 어노테이션 설정을 같이 사용

  • context 네임스페이스 annotation-config 태그를 xml 설정 파일에 추가해줘야 한다.
    <context:annotation-config />
클래스의 bean 생성 - IoC
<bean id="아이디" class="클래스 경로">
</bean>
bean에 다른 bean 또는 값을 주입 - DI 

<bean id="아이디" class="클래스 경로">
    <property name="프로퍼티이름" value="값"/>
</bean>

<bean id="아이디" class="클래스 경로">
    <property name="프로퍼티이름">
      <ref bean="다른 bean의 id"/>
    </property>
</bean>

results matching ""

    No results matching ""