1. IoC(Inversion of Control)이란?
Inversion Of Control을 그대로 번역해 보면 제어의 역전이다. 기존 자바 프로그램에서는 각 객체들이 프로그램의 흐름을 결정하고 필요한 객체를 직접 new ~ 해서 객체를 생성하고 사용했다. 즉 모든 작업을 프로그래머가 제어하며 추상 객체가 아닌 구현 객체가 프로그램의 제어 흐름을 스스로 조종했다. 다르게 말하면 의존성이 높은 코드를 만드는 것이다.
하지만 프로그램의 제어 흐름에 대한 권한을 직접 제어하는, 즉 의존성이 높은 코드는 코드의 유지 보수를 어렵게 하고 재사용을 방해한다. 그렇기 때문에 객체에 대한 제어권을 객체가 직접 가지고 있는 것이 아니라 외부에서 관리하는 것을 제어의 역전(IoC)라고 한다. 프로그램은 내가 어떤 유형의 객체를 생성하고 실행하는지 전혀 모른채 외부에서 주입받은 객체를 가지고 자신의 로직을 묵묵히 수행해야 한다.
제어의 역전을 실현하기 위해 Spring은 의존성 주입(DI), IoC Container를 사용하는 것이다.
2. 의존성 주입(DI - Dependency Injection)란?
의존성 주입은 내가 포스팅한 글 중에 DI(Dependency Injection)란? 포스팅이 있기 때문에 자세히 알고싶은 사람은 저 글을 참고하면 좋을 것 같다. 여기서는 간단하게만 다시 정리하려고 한다.
의존성 주입이란 유지 보수에 유리한 코드, 객체지향적으로 잘 설계된 코드란 객체간에 의존성이 낮아야 한다. SOLID원칙중 단일 책임 원칙(SRP), 의존관계 역전 원칙(DIP) 사실 이 두 원칙만 한정되어 있는 것이 아닌 모든 SOLID원칙을 만족 하기 위해 기초가 되는 것이 의존성 주입이다.
SOLID원칙 중 Single Responsibility Principle 단일 책임 원칙의 정의는 "한 클래스는 하나의 책임만 가져야 한다." 이다. 의존관계 역전 원칙(프로그래머는 추상화에 의존해야지 구체화에 의존하면 안된다.)과 묶어서 생각하면 이상적인 코드는 상위 계층인 인터페이스 타입의 객체에 대해서는 알고있고 인터페이스를 구현한 객체에 대해서는 몰라야 한다. 이 문장을 다르게 말하면 구현 객체에 대해서 의존성이 없는 것이다. 이 좋은 코드를 만들기 위해, 인터페이스를 구현한 객체를 외부에서 주입받아 사용하기 위해 필요한 방법이 바로 의존성 주입이라는 방법이다.
3. IoC Container / DI Container 란?
IoC 컨테이너, DI 컨테이너라고 흔히 말한다. 처음 이 개념을 들으면 이게 뭔데?라는 생각이 든다. 쉽게 생각해보면 IoC를 해주는 컨테이너, DI를 해주는 컨테이너 라고 생각하면 쉽다. IoC Container와 DI Container는 동일한 단어이다.
"IoC를 해준다" 라는 말은 "의존성을 외부에서 주입해준다."와 동일한 말이다. 의존성을 외부에서 주입하기 위해서는 내가 쓴 DI포스팅을 봤다면 알 것이다. 바로 생성자를 통한 의존성 주입을 해야한다. 생성자를 통한 주입이란 "외부에서 사용할 객체를 만들어서" 생성자를 통해 보내주면 생성자 파라미터를 통해 인터페이스 타입으로 객체를 받아서 사용한다.
위에 강조해놓은 "외부에서 사용할 객체를 만들어서" 이 부분을 담당하고 있는게 IoC 컨테이너/DI 컨테이너이다. 즉 DI 컨테이너는 스프링 빈들을 생성 및 관리하며, 스프링 빈 간의 의존관계 주입을 대신 해준다.
4. Spring Bean
DI 컨테이너가 관리하는 Java 객체를 Spring Bean이라고 한다. DI 컨테이너에 의해 생성되고 라이프 사이클을 수행하고 의존성 주입이 일어나는 객체를 Spring Bean이라고 하며, 이 Spring Bean은 개발자가 제어하는 것이 아닌 스프링에게 제어권이 넘어간 객체를 Spring Bean이라고 부른다.
만들고 싶은 서비스를 스스로 공부하고 만들어 보면서 기록하는 개인 공부 블로그입니다.
내용 중 최적화가 가능한 부분 혹은 궁금한 점은 언제든지 댓글로 남겨주세요🧐