본문 바로가기

IT/Spring

[Spring] 의존성 주입(Dependency Inject,DI)이란?

 

의존성 주입을 이해하기 전에 의존성에 대해서 먼저 알아보겠습니다.

1. 의존성이란?

의존의 사전적 의미는 "스스로 하지 못하고 누군가에게 도움을 받음" 입니다.

그렇다면 의존성은 무엇일까요? 

의존성이란
어떤 객체가 생성되기 위해 다른 객체가 꼭 필요한 상태를 의미합니다.
의존성은 new 연산자를 통해 발생합니다. 의존성이 높아지면 결합도 또한 높아집니다. 

결합도가 높으면 해당 클래스를 수정할 경우 참조하고 있는 다른 클래스도 함께 이해해야합니다.  
왜냐하면 무작정 수정했다가는 사이드 이펙트가 발생할 수 있기 때문입니다.

그리고 결합도가 높은 클래스는 재사용하기 힘듭니다. 

 

1) 의존성 예제

public class Windows {

    public void booting() {
        System.out.println("Windows booting !");
    }
}

public class Computer {

    private Windows os;

    public Computer() {
        this.os = new Windows();
    }

    public void booting() {
        os.booting();
    }
}
Computer 클래스가 Windows 클래스를 참조하고 있는 상태입니다.  

만약 Mac, Linux 등 다양한 OS 객체를 전달 받으려면 소스를 수정해야합니다.
이는 코드의 유연성을 떨어트리고 중복 소스가 생기며 가독성 또한 떨어트리는 원인이 됩니다.

이러한 문제를 해결하기 위한 방법 중 하나는 바로 의존성 역전(Dependency Injection)을 이용하는 방법입니다.

 

2) 의존성 주입(Dependency Injection) 예제

public interface OS {
    public void booting();
}

public class Windows implements OS {

    @Override
    public void booting() {
        System.out.println("Windows booting !");
    }
}

public class Linux implements OS {

    @Override
    public void booting() {
        System.out.println("Linux booting !");
    }

}

public class Computer {

    private OS os;
    //외부에서 객체를 주입받는다.
    public Computer(OS os) {
        this.os = os;
    }

    public void booting() {
        os.booting();
    }
}

public class Main {
    public static void main(String[] args) {

        OS windows = new Windows();
        Computer windowsComputer = new Computer(windows);

        OS linux = new Linux();
        Computer linuxComputer = new Computer(linux);
        
        windowsComputer.booting();
        linuxComputer.booting();
    }
}


단순히 생성자를 통해 외부에서 객체를 전달받았다고 의존성 주입이라고 하지 않습니다.
만약 Windows 객체를 생성자로 주입받았다면, 외부로 부터 객체를 주입받았지만, 결합도가 낮아졌다고 할 수 없습니다.
이전에 존재했던 문제를 똑같이 안고 가는 것 입니다.

제대로 된 의존성 주입을 하려면 추상화된 객체를 외부에서 주입 받아야 합니다.
Computer 클래스의 생성자는 외부에서 생성된 객체(OS 인터페이스를 구현한 객체)를 전달 받습니다. Windows 객체를 전달 받았을 때보다 결합도가 낮아 졌으며, OS가 새로 추가되더라도 Computer 클래스는 수정하지 않아도 됩니다.

 

2. 의존성 주입이란?

의존성 주입이란 추상화된 객체를 외부에서 주입받는 것을 의미합니다. 
(ex : OS 인터페이스를 구현한 Windows 또는 Linux)

의존성 주입은 생성자, setter, field 등 다양하게 구현할 수 있습니다.
의존성 주입의 장점

1) 테스트가 용이합니다.
2) 재사용성과 유연성이 높아집니다.
3) 코드의 중복이 없어지고, 단순해집니다.
4) 코드의 가독성이 좋아집니다.
5) 종속성과 결합도가 낮아집니다.

참조

https://engkimbs.tistory.com/602?category=767795
https://medium.com/@jang.wangsu/di-dependency-injection-%EC%9D%B4%EB%9E%80-1b12fdefec4f