IoC는 Inversion of Control 의 줄임말입니다.
Inversion of Control는 ‘제어의 역행‘이라는 뜻입니다.
“IoC와 AOP를 지원하는 경량 컨테이너 프레임워크”를 다시 해석하면,
제어의 역행을 지원하는 / 일반적 형태의 객체를 생성하고 관리할 수 있는 / 컨테이너 프레임워크라고 할 수 있겠습니다.
IoC의 목표
‘제어의 역행’ 즉, IoC의 목표는 무엇일까요?
어플리케이션을 구성하는 객체들간의 느슨한 결합을 목표로 합니다.
느슨한 결합 == 낮은 결합도를 유지하는 것이 목표입니다.
결합도가 높게 되면 개발자 입장에서는 유지보수가 힘듭니다.
뭔가 꼼꼼히 결합되 있으면 하나를 고치기 위해 결합되어 있는 것들을 다 풀어야 되니 굉장히 복잡할 수 밖에 없습니다.
원래 의존관계에 있는 객체를 변경할 때 소스코드(자바코드)를 수정해야하지만,
IoC를 적용하게 되면 객체 생성을 소스코드로 처리하지 않고 컨테이너가 대신 판단하여 처리합니다.
결론
IoC를 적용하면 객체 생성을 컨테이너가 대신 판단하기 때문에 개발자가 처리해야 할 소스코드가 없습니다.
즉, 소스코드의 결합도가 낮아졌기 때문에 유지보수가 편리해집니다.
개발자의 코드 개입을 줄여가는 것이 목표라고 볼 수 있습니다.
어떻게 결합도를 낮출 수 있나?
서블릿 컨테이너로 예시를 들어보겠습니다.
사용자 --web.xml--> 톰캣 -> Dispatcher , 서블릿(Controller) -> View(jsp)
사용자가 톰캣을 실행시킬때, 매핑된 서블릿이 있는지 확인해야하기 때문에 web.xml을 보게됩니다.
web.xml을 본다는 얘기는 뭔가 설정파일을 본다고 해석해서 보면 됩니다.
사용자가 톰캣을 구동시킬때 서블릿 컨테이너는 뭔가 설정사항이 있는지 참고하여 프로그램을 돌리게 된다는 겁니다.
Dispatcher는 .do / .mem / .jsp 에 대하여 각각 알맞는 Controller로 지시를 하게 되고,일을 끝내고 다시 Dispatcher로 돌아오면 포워딩해서 View단으로 화면을 넘겨줍니다.
이때 우리의 목표는? 결합도를 낮추는 것입니다.
즉 소스코드를 손 안대는게 목표입니다. == 수정되는 코드를 줄이는 게 목표입니다.
어떻게 수정되는 코드를 줄일 수 있을까요?
우선 객체 생성을 컨테이너가 대신 판단하고 처리하게 해야 합니다.
톰캣 서블릿 컨테이너가 판단하게 하기 위해 web.xml 파일을 뒀었던 것처럼
마찬가지로 xml파일을 하나 둬서 컨테이너가 대신 판단하게 할 수 있습니다.
이때 xml 파일에 DI(Dependency Injection) : 의존성 주입 을 해야 합니다.
더 들어가보겠습니다.
사용자 --web.xml--> 톰캣 -> Dispatcher , 서블릿(Controller) -> View(jsp)
UI(User Interface) --> Service --> DAO --> DB
UI에서 유저가 뭔가 서비스를 이용하면 DAO에 들어가게되고, DAO가 DB를 건드려서 원하는 결과를 가져와서 다시 유저에게 보여주게됩니다.
이 과정에서 Controller에 만약 A1 a = new A1(); 이 있었는데 객체가 A2로 수정이 됐다고 가정해봅시다.
A1 a = new A1();
A2 a = new A2();
그렇다면 이렇게 변경해서 써야합니다. 이게 원래 방식입니다.
그런데 이렇게 코드를 변경하면 실수를 할 수도 있고 용이하지 않기 때문에
A a = new A1();
이렇게 한번 써볼까? 까지 생각하게 됩니다.
A a
부분은 바꿀 필요가 없게 된 겁니다.
이럴 때 필요한게 Interface 개념입니다.
A1과 A2를 모두 다 가지고 있어야 하는 A인 겁니다.
이제 앞으로
A a = new A1();
뒷부분에 new A1()
을 넣을지, new A2()
를 넣을지 컨테이너가 대신 판단하게 하게 할 겁니다.
그러기 위해서 설정파일 .xml 이나 혹은 Annotation(어노테이션)을 이용해서 객체 생성을 외부에서 설정하게 할 것입니다.
(객체 생성을 외부에서 설정하겠다 == DI를 하겠다 == 의존성 주입하겠다)
최종정리
스프링 프레임워크는 일반적인 형태의 객체를 생성하고 관리할 수 있는 일종의 컨테이너 프레임 워크입니다. 뭐를 지원하는? 제어의 역행을 지원하는.
제어의 역행이라는 말은 어려우니까, 낮은 결합도를 유지할 수 있게 도와주는 것이라고 이해합시다.
이 말의 뜻은 개발자가 직접 객체 생성을 작성하거나 변경하는게 아니라
.xml이나 외부 어노테이션으로 컨테이너가 대신 판단하고 처리 하게 하겠다는 겁니다.
이러한 개념을 DI(Dependency Injection), 의존성 주입 이라고 합니다.