개발바닥곰발바닥
Published 2022. 4. 1. 01:33
[Spring] IoC와 DI의 이해 JAVA/Spring
728x90

IoC(Inversion of Control)

기존의 프로그램은 클라이언트 구현 객체가 스스로 필요한 서버 구현 객체를 생성하고, 연결, 실행하므로써 구현 객체가 프로그램의 제어 흐름을 스스로 조종했다. (객체를 생성하고, 객체 간의 의존성을 만들어주고, 초기화하고 객체를 호출하는 등)

 

그러나 IoC은 제어의 역전이라는 의미로 프로그램의 제어 흐름을 개발자가 직접 제어하는 것이 아니라 외부에서 관리하는 것을 제어의 역전(IoC)이라고 한다.

 

Spring에서 IoC는 객체의 대한 제어권이 스프링 컨테이너로 역전되기 때문에 xml 파일이나 어노테이션 방식으로 스프링 컨테이너에 Bean(객체)를 등록하면, 스프링 컨테이너에서 Bean의 생명주기(생성, 의존성 설정, 초기화, 소멸)를 모두 관리한다.

 

IoC를 사용함으로써 얻을 수 있는 장점은 다음과 같다.

  1. 의존성을 역전시켜 객체 간의 결합도를 줄이고 유연한 코드를 작성할 수 있다. → 코드의 재사용성이 좋아지고, 유지 보수가 편해진다.
  2. Spring Container(IoC Container)가 Bean을 관리해주므로 개발자는 객체 관리 대신 다른 부분에 더 집중할 수 있다.

DI (Dependency Injection)

DI란 의존성 주입이라는 의미를 가지고 있다. Spring에서 DI는 어떤 객체에 스프링 컨테이너가 또 다른 객체와 의존성을 맺어주는 데, 이는 사용자가 객체를 직접 생성하는 게 아니라 외부에서 생성 한 후 주입시켜 주는 것을 의미한다.

DI를 적용해서 의존성을 주입하는 경우와 의존성을 직접 맺는 경우를 코드로 보면 다음과 같다.

DI를 사용하지 않는 경우

public class A {
    private B b;
    //의존성 주입을 사용하지 않고 A class에서 직접 B 객체를 만들어 의존성 적용
    public A() {
        b = new B();
    }
}

DI를 사용한 경우

DI를 구현하는 방법은 두 가지가 있다. 첫 번째로는 생성자를 이용하는 것이고 두 번째는 setter 메소드를 이용하는 것이다.

 

1.생성자 이용

public class A {
    private B b;
    public A(B b) {
        this.b = b;
    }
}

public class C {
    private A a = new A(new B());
}

2.setter 메소드 이용

public class A {
    private B b = new B();
    public void setB(B b) {
        this.b = b;
    }
}

public class C {
    private A a = new A(new B());
}

두 방법 모두 A 클래스 외부에서 의존성을 주입 받는 것을 확인할 수 있다.

 

그렇다면 DI를 구현하면 어떤 장점을 얻을 수 있을까?

1. 객체 간의 결합도, 의존성이 줄어든다.

    의존한다는 것은 의존 대상의 변화에 영향을 받는다는 것이다. 하지만 DI로 의존 관계를 분리하게 되면

    주입받는 대상이 수정되도 그 구현을 수정할 필요가 없어지거나 줄어든다.

2. 코드의 재활용성이 높아진다.

3. Unit Test가 용이해진다. (테스트하기 좋은 코드가 된다)

   DI로 구현하면 A의 테스트를 B 테스트와 분리하여 진행할 수 있게 된다.

4. 가독성이 높아진다.

728x90
profile

개발바닥곰발바닥

@bestinu

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!