제어의 역전.
- 프로그래머가 개발을 할 때, 외부 라이브러리를 호출하여 객체의 생성부터 시작해서 메소드 호출, 소멸까지 모든 생명주기를 프로그래머가 제어한다면, 프로그램의 제어의 권한이 애플리케이션에 있다 라고 말한다.
- 이 프로그램의 제어를 외부 프레임워크가 한다면, 프로그램의 제어의 역전이 일어났다 라고 말할 수 있다.
- 즉, 애플리케이션 외부에서 애플리케이션의 흐름을 제어하는 설계 원칙을 IoC 설계 원칙이라 한다.
프레임워크가 IoC가 적용된 기술이다.- 예를 들면, 스프링에서 @Autowired를 사용함으로써 개발자가 코드를 작성하여 직접 의존관계를 설정해주는 것이 아닌, 프레임워크에서 자동으로 의존관계를 설정해주어 IoC 설계에 맞추었다고 할 수 있다.
- 객체 간 결합을 느슨하게 만들어 유연하고 확장성 뛰어는 코드를 작성할 수 있게 하여 유지보수를 용이하게 해준다.
- 개발자는 애플리케이션의 흐름보다 핵심 비지니스 로직에 더욱 집중할 수 있다.
의존관계 주입.
- 의존관계는 정적인 클래스 의존관계와 동적인 인스턴스 의존관계로 분리해서 생각할 필요가 있다.
위 클래스 다이어그램을 보면, OrderServiceImpl 클래스는 MemberRepository, DiscountPolicy 클래스에 의존한다는 것을 알 수 있다. 하지만, MemberRepository, DiscountPolicy에는 어떤 클래스가 인스턴스화 될 지 알 수 없다.
위 객체 다이어그램을 보면 런타임에 인스턴스가 생성되고 클라이언트와 의존 관계가 연결되는 것을 알 수 있다. 이를 의존관계 주입이라 한다.
위 예제에서, 할인 정책을 인터페이스로 구현하지 않고, 만약 클라이언트 코드에서 직접 클래스에 접근하는 방식으롤 구현했다면 할인 정책이 변경되면 클라이언트 코드를 뜯어고쳐야 하는 상황이 벌어진다.
하지만, 할인 정책을 인터페이스로 만들고, 구현체들이 그 인터페이스를 상속받도록 하여 런타임에 의존관계를 주입하면, 클라이언트는 인터페이스에만 의존하기 때문에 할인 정책이 변경되어도 코드를 변경하지 않아도 된다. (객체 간 결합도가 낮다) 즉, 클라이언트는 할인 정책에 대해 아예 모르고, 비지니스 로직만 잘 수행하면 된다.
객체를 생성하고 생명주기를 관리며 의존관계를 관리하는 컨테이너이다.
스프링에서는 스프링 컨테이너가 DI 컨테이너이다.
**참고
인프런 김영한 스프링 강의
https://hudi.blog/inversion-of-control/
https://beststar-1.tistory.com/33