본문 바로가기
Back/Spring

의존성(Dependency)

by Hyeon_ 2022. 1. 5.

의존성 (Dependency)

객체 간 의존성. 한 클래스가 다른 클래스의 객체를 통해 그 클래스의 메소드를 실행할 때 이를 의존한다고 표현한다.

DI를 사용하는 이유

  • 의존하는 객체의 클래스가 변경되거나 다른 클래스의 객체를 사용하게 될 경우
  • 의존 관계(결합 상태)에 있는 다른 모든 클래스들의 소스 코드도 변경해야 하는데 의존성 주입 방법을 사용하면, 클래스 결합 상태를 변경하거나 객체를 주입하는 부분만 수정하면 되므로 수정할 코드의 양을 줄일 수 있다는 장점이 존재한다.

스프링 의존성 주입 방법

  • XML을 이용한 방법
    • xml 설정 파일에 <bean> 설정
  • Annotation을 이용한 방법
    • 자바 코드에서 @어노테이션으로 설정
      • @Controller / @Service

1. 스프링을 사용하지 않는 DI

(1) DI를 사용하지 않는 코드

  • 의존성이 무엇인지 확인하는 예제
  • 클래스 간 의존성은 존재하나, Injection 아님
  • 의존성 관계가 있는 객체를 개발자가 new 연산자를 이용해서 직접 생성

(2) DI를 사용한 코드(의존성 존재 / Injection이지만 스프링 방식이 아님)

  • DI 개념이 무엇인지 확인하는 예제
  • (1) 생성자 기반 DI
  • (2) Setter 기반 DI

 


 

스프링 프로젝트 생성

  • File > new > Maven Project -> Create a simple project
  • Group Id : com.di_project.ex (도메인 이름)
    • 도메인 이름 형식 : com.company.app
  • Artifact Id : di_01 (프로젝트 이름)

예제1 (스프링을 사용하지 않는 DI - D를 사용하지 않는 코드)

클래스

  • NameService
  • NameController
    • new 연산자를 사용해서 NameService 클래스 객체 생성하여 의존성 주입 (DI는 아님)
  • NameMain
NameService
public class NameService {
    public String showName(String name) {
        System.out.println("NameService showName() 메소드");
        String myName = "내 이름은 " + name + " 입니다.";
        return myName;
    }
}
NameController
public class NameController {
    // 원하는 곳에서 new 연산자사용하여 객체 직접 생성
    // 의존성은 존재하나 DI는 아님
    NameService nameService = new NameService();

    // 이름 전달받아서 NameService 클래스의 showName() 메소드에 전달하고
    // NameService로부터 전달받아 이름 출력하는 메소드
    public void show(String name) {
        System.out.println("NameController : " + nameService.showName(name));
    }
}
NameMain
public class NameMain {
    public static void main(String[] args) {
        NameController controller = new NameController();
        controller.show("홍길동");
    }
}

예제2 (스프링을 사용하지 않는 DI - 생성자 기반 DI)

  • 의존성 관계에 있는 객체를 new를 통해 직접 생성하지 않고 생성자를 통해 외부에서 전달(주입. Injection)
NameService : 위와 동일
NameController
public class NameController {
    NameService nameService;

    // NameService 객체를 new 연산자를 통해 직접 만들지 않고 생성자를 통해 객체를 전달받음
    // 의미 : 생성자를 통해 외부에서 주입 받음 (injection)

    public NameController(NameService nameService) {
        // 전달받은 값으로 멤버변수 초기화
        this.nameService = nameService;
    }

    public void show(String name) {
        System.out.println("NameController : " + nameService.showName(name));
    }    
}
NameMain
public class NameMain {

    public static void main(String[] args) {
        // NameController에게 전달할 NameService 클래스 객체 생성
        NameService nameService = new NameService();

        // NameController에게 생성자를 통해 주입
        NameController controller = new NameController(nameService);
        controller.show("이몽룡");
    }
}

예제3 (스프링을 사용하지 않는 DI - Setter기반 DI)

  • 생성자를 구현할 때 전달해야 할 객체가 많은 경우 일일이 생성자를 구현하는 것이 번거로울 수 있음 -> Setter 메소드 사용하여 의존성 주입
NameService : 위와 동일
NameController
public class NameController {
    NameService nameService;

    // 생성자 없고
    // Setter 메소드 통해 외부에서 주입 받음
    public void setNameService(NameService nameService) {
        this.nameService = nameService;
    }

    public void show(String name) {
        System.out.println("NameController : " + nameService.showName(name));
    }    
}
NameMain
public class NameMain {

    public static void main(String[] args) {
        NameService nameService = new NameService();
        NameController controller = new NameController();

        // Setter 메소드를 통해 nameService 객체 전달(주입: Injection)
        controller.setNameService(nameService);
        controller.show("성춘향");
    }
}

'Back > Spring' 카테고리의 다른 글

Spring - AOP(Aspect Oriented Programming)  (0) 2022.01.05
Spring - Annotation(어노테이션)  (0) 2022.01.05
Spring - Singleton(싱글톤)  (0) 2022.01.05
스프링 프레임워크 종류 및 특징  (0) 2022.01.05
스프링 프레임워크  (0) 2022.01.05