DI와 IoC

Jang990·2023년 3월 17일
0

IoC(Inversion of Controll)

IoC란 제어의 역전을 말합니다. 풀어서 말하면 프로그램의 흐름에 대한 제어권을 스프링과 같이 외부에서 가져가는 것입니다.

아마 이렇게 처음 글자로만 접하시면 이해가 안될 것입니다.

이해를 위해 다음과 같은 서비스가 있다고 생각해보겠습니다.

public interface Calculator {
	...
}

@RequiredArgsConstructor
public class OrderService {
	private final Calculator calculator;
    
    public void logic() {
    	... 관련 로직
    }
}

public class FastCalculator implement Calculator { ... }
public class SlowCalculator implement Calculator { ... }

OrderService는 주문 가격을 계산하기 위해 Calculator를 사용합니다.


🚩 In 순수 자바 코드

위 서비스를 main함수를 통해 실행시키려면 다음과 같이 코드를 작성할 수 있습니다.

public static void main(String[] args) {
	Calculator calculator = new FastCalculator();
	OrderService orderService = new OrderService(calculator);
    orderService.logic();
}

위와 같이 실행시키면 프로그램에 대한 제어를 개발자가 직접 할 수 있습니다. 만약 FastCalculator대신 SlowCalculator라는 구현체를 쓰고 싶다면 개발자가 직접 코드를 바꾸면 됩니다. 이렇게 main함수 안에서는 개발자의 의도된 흐름대로 제어되며 실행될 것입니다.


🚩 In 스프링

그럼 이제 스프링에서 OrderService를 사용하고 싶을 땐 어떻게 해야 할까요?

다음과 같이 애노테이션을 추가해주어 객체가 스프링 컨테이너에 등록되어 관리되도록 만듭니다.

@Component // 추가
@RequiredArgsConstructor
public class OrderService {
	...
}

@Component // 추가
public class FastCalculator implement Calculator{
	...
}

그리고 스프링에서는 ApplicationContext를 통해 OrderService를 사용할 수 있을 것입니다.

@Autowired
ApplicationContext applicationContext;

public static void main(String[] args) {
	OrderService orderService = applicationContext.getBean(OrderService.class);
    orderService.logic();
}

이렇게 된다면 FastCalculator대신 SlowCalculator라는 구현체를 쓰고 싶어도 해당 main함수에서 할 수 있는 것이 없습니다.
스프링 컨테이너에 등록되어 의존관계를 주입 받기 때문에 개발자가 제어할 수 없는 것입니다.


프로그램의 제어의 흐름이 외부에 의해 관리되는 것. 이것을 제어의 역전(IoC)이라 말합니다.

= 객체의 생성과 관리를 프레임워크나 컨테이너에 위임하는 것


DI(Dependency Injection)

DI(Dependency Injection)는 의존관계 주입을 의미합니다.
객체 간의 의존 관계를 외부에서 주입하는 방식으로 객체를 생성하고 연결합니다.

계속 '의존관계', '의존'이라고 말하고 있는데 "의존"이 무엇일까요?

🙄 의존?

어떤 객체도 섬이 아닙니다. 객체들은 특정한 목표(기능 구현)를 이루기 위해 역할과 책임을 가지고 협력에 참여합니다. 즉 객체는 자신의 기능을 수행할 때 다른 객체의 도움이 필요하다는 의미입니다.

앞서 OrderServiceCalculator의 관계를 생각해보겠습니다.
OrderService는 주문 가격을 계산하고 싶다면 Calculator의 도움이 필요합니다. OrderService가 주문 가격을 계산하는 기능은 존재하지 않습니다.

이런 경우를 "OrderServiceCalculator의존한다"고 말합니다.


앞서 본 코드에 applicationContext.getBean(OrderService.class);를 다시 봐보겠습니다.

@Autowired
ApplicationContext applicationContext;

public static void main(String[] args) {
	OrderService orderService = applicationContext.getBean(OrderService.class);
    orderService.logic();
}

개발자는 OrderServicenew 연산자를 통해 만들지 않았습니다. 그러나 외부(스프링 컨테이너)에서 OrderService가 의존하는 Calculator를 알아서 연결해 주었습니다.

이렇게 외부에서 알아서 연결해주는 것을 의존관계 주입(DI)이라고 말합니다.

IoC는 DI(Dependency Injection)을 포함하는 개념이기도 하답니다.

출처

인프런 - 김영한, 스프링-핵심-원리-기본편

도서 - 객체지향의 사실과 오해

profile
공부한 내용을 적지 말고 이해한 내용을 설명하자

0개의 댓글