본문 바로가기

공부방/Spring

IoC(제어의 역전), DI(의존성 주입) 이란??

출처 : http://blog.daum.net/crintover25/89

 


 

본 문서를 읽는 독자들에게 부탁하나 하노라면 토비의 스프링 3와 함께 읽어주길 바란다.

많은 부분이 이 책에서 인용되었고 필자 또한 책을 읽고 이해가 가지 않는 부분에 대해 적어놓는 형태인지라

책과 함께 블로그를 읽는다면 큰 도움이 될 것이라 생각되기 때문이다.

 


 

토비의 스프링은 다음과 같이 말한다스프링은 거대한 컨테이너임과 동시에 Ioc/DI를 기반으로 하고 있는 거룩한 존재이며 서비스 추상화를 통해 삼위일체로 분리되는 3단 변신로봇이라고 한다. 이럴수가! 뭔말하는지는 하나도 모르겠지만 일단 말만 들어도 엄청난데다 가격까지 공짜다. 게다가 이걸 쓰는 사람들마다 칭찬 또 칭찬 일색이니 궁금해서 참을 수가 없다.

 

근데 말이다…. 필자는 스프링의 지독한 뉴비이므로 여기서 뉴비답게 눈치없게 한번 굴어보려 한다. 일단 스프링이 대단하고 무지 엄청나다는 건 알겠는데…. 컨테이너는 뭐고 IoC/DI는 뭐란 말인가? 평생 살면서 컨테이너란 위의 사진같은 것 밖에 모르는데… 그리고 서비스 추상화? 난 아직 서비스가 뭔지도 모르겠다.

 

 

컨테이너란?

 

컨테이너란 당신이 작성한 코드의 처리과정을 위임받은 독립적인 존재라고 생각하면 된다컨테이너는 적절한 설정만 되있다면 누구의 도움없이도 프로그래머가 작성한 코드를 스스로 참조한 뒤 알아서 객체의 생성과 소멸을 컨트롤해준다. 거기다 컨테이너를 이용함으로써 얻게되는 이득은 어마어마 하며, 이런 강력한 기능을 무료로 이용할 수 있다는 점 또한 엄청나다.

 

허나 소수의 독립심 강하고 줏대있는 사람들은 내가 잘 알지도 못하는 프로그램을 무작정 써야 한다는 것에 반감을 살 수도 있다. 게다가 프로그래머가 다른 라이브러리에 의존하지 않고 직접 코드를 작성해나간다면 완성된 프로그램에 대한 이해도 또한 상상을 초월할 것이다. 혹은 인간이 그렇게 줏대없이 프로그램만 의존하다가 터미네이터나 매트릭스 같은 세상이 되버리면 어떡하냐고 필자에게 따질 수도 있는 것이다.

 

만약 이러저러한 이유로 컨테이너를 거부하겠다면 필자는 굳이 사용하지 않아도 상관은 없다고 말하겠다. 진심으로 실력만 된다면사용자가 직접 컨테이너를 만들어써도 상관은 없다.

 

그러나 직접 컨테이너를 구현해보고자 키보드에 손을 올렸다면 아마 배보다 배꼽이 더큰 컨테이너의 어마어마한 기능에 입이 쩍벌어질 것이다. 빈정상하라고 하는 말은 아니지만 사실 당신이 구현하고자 하는 코드와 컨테이너의 구현 코드는 비교도 안될 정도로 수준차가 어마어마하다. 그러므로 코드의 이해가 당장 힘들어지고 뭐가뭔지 모르겠더라도 일단 막강한 기능을 제공하는 컨테이너를 이용하기로 하자.

 

다시 말하지만 프로그래머가 작성한 코드는 컨테이너를 사용하게 됨으로서 프로그래머의 손을 떠나 컨테이너의 영역으로 떠나버리게 된다. (정확히 말하자면 컨테이너가 맘대로 객체를 생성하는 게 아니라 프로그램을 이용하는 이용자의 호출에 의해 컨테이너가 동작하게 되는 구조이다.) 여하튼 컨테이너를 이용한다면 우리의 골치아픈 문제는 다 컨테이너 알아서 해주므로 쓸데없는 버그나 난해한 과제들에 골치 아파질 이유가 없어진다. 당신은 컨테이너의 기능을 이용하고 사용 중 오류가 있으면 일단 무조건 개발사 탓을 하면 되므로 회사에서 짤릴 가능성까지 어느 정도 낮아진 셈이다!

 

내친 김에 당신이 필자와 같은 初뉴비라면 임기응변을 위해서라도 반드시 스프링의 개발자와 자바의 개발자 정도가 누군지는 알아두어야 한다. 이런걸 미리미리 알아둬야 나중에 직장 상사가 괜한 버그로 트집을 잡을 때 무조건 이 사람들 탓으로 돌릴 수 있게 된다.

 

자바의 아버지, 제임스 고슬링 - 선 마이크로시스템즈라는 회사와 함께 자바라는 언어를 탄생시키는데 혁혁한 공을 세운 인물이며 SUN이 오라클로 인수된 뒤 얼마 지나지 않아 회사를 퇴임하고 현재 구글에서 근무 중이다. 개인적으로 C UNIX를 만든 데니스 리치 다음으로 훌륭한 프로그래머라고 생각한다.

스프링 혁명가로드 존슨 - 프로그래밍 계의 락스타같은 존재라 할 수 있다. 그가 한 유명한 말로 "항상 프레임워크 기반으로 접근하라"라는 말이 있는데 이 말은 곧 당신이 한 클래스에서 DB에 넣고 빼는 등 온갖 짓거리로 코드를 짜고 있다면 당신이 어디가서 프로그래밍의 프자도 꺼내서는 안된다는 말이다.

 


다시 본론으로 돌아와 스프링과 더불어 대표적인 컨테이너를 예로 들자면 톰캣과 같은 WAS(Web Application Service)를 들 수 있다. 우리가 열심히 작성한 서블릿을 써줄지 말지는 톰캣이 결정하므로 당연히 컨테이너 아닌가. 혹여나 그래도 이해가 가지 않는다면… 그냥 당신이 쓰고 있는 코드가 도통 언제 호출될지도 감이 안오는 막막한 상태라면 올바르게 컨테이너를 이용하고 있다고 하자. 그런 의미에서 컨테이너는 당신의 사수나 수석 프로그래머라고 할 수 있다. 내가 쓴 코드를 그 사람들이 써줄지 말지는 모르는 일이니 말이다.

 

 

IoC/DI?

 

IoC/DI Inversion of Control Dependency Injection의 줄임말이다. 한글로 번역하면 제어의 역전, 의존적 주입이라고 하는데 목에 힘을 좀 빼고 솔직히 말하자면 살다살다 한글로 번역까지 했는데 이해 못할 말이 튀어나올 줄은 몰랐다. 그래서 나름 좀… 쪽팔려도 뉴비의 표현으로 바꾸자면 "대신 해줌(IoC)" "미리 찜해 놓음(DI)"라고 잠시 명칭을 정정하도록 하겠다.

 

일단 IoC란 무엇인가당신이 위의 컨테이너의 설명글을 꼼꼼히 읽어왔다면 IoC는 지금 당신이 생각하고 있는게 맞다. 바로 컨테이너다. 컨테이너는 당신이 작성한 코드 컨트롤(객체의 생성과 소멸)을 대신 해주는데 IoC덕분에 우리는 미친 사람마냥 언제 호출될지도 모르는 코드를 마음껏! 칠 수 있게 되었다.

 

사실 IoC는 스프링만의 코딩방식은 아니고 다른 프레임워크에서도 사용되는 방식인데 굳이 스프링만 우리는 IoC 방식이라고 목이 힘주어 강조하는 이유는 스프링은 정말 철저하게 IoC 방식을 써먹었다는 것이다. 그러므로 우리가 여기서 얻을 수 있는 결론은 어디가서 스프링 좀 안다고 IoC가 스프링만의 고유한 방식이라고 떠벌리면 안된다는 것일테다.

 

그렇다면 DI란 또 무엇인가? 이것은 마치 당신이 받아먹기도 전에 미리 받아먹겠노라고 선언하는…, 주는 놈은 생각도 않았는데 먼저 말부터 꺼내놓는 파렴치한 코딩방식이라고 할 수 있다. 예를 들어 당신이 조촐한 회식으로 사장님과 중국집을 갔는데 당당히 "저는 짜장면 안먹고 양장피 먹겠습니다."라고 선언한다면 당신은 DI개념이 아주 확실한 프로그래머인 셈이다.

 

게다가 사실 DI 마저도 스프링만의 고유한 방식은 아니라는 거다. DI란 전설과도 같은 프로그래밍 예언서 GoF 중에서 가장 유명한 전략패턴을 일종의 프레임워크 처럼 편리하게 사용할 수 있도록 만든 것이라 할 수 있는데 스프링은 이런 전설로만 알아오던 전략패턴을 뉴비마저도 산소 호흡하듯 능수능란하게 사용하게끔 편리화하였다.

 

좀 더 구체적으로 DI에 대해 말하자면, DI방식으로 코드를 작성한다면 현재 사용하고 있는 객체의 메서드가 어떻게 작성되었는지 알 필요가 없으며 솔직히 그 클래스가 기능을 잘 구현했는지 조차도 알 필요가 없다. 그저 당신이 확인할 사항은 클래스의 기능을 추상적으로 묶어둔 인터페이스만 갖다 쓰면 그만이다. 나머지는 스프링에서 찜한 걸 연결시켜줄테니 말이다.

 

아래 그림은 위의 글로만 써놓은 전략패턴과 DI에 대해 정말 간단히 예제로 만든 코드이다.

 



먼저 말했듯 DI는 스프링만 가지고 있는 고유의 기능이 아니므로 자바의 오브젝트 단위에서도 DI의 구현이 가능하다. 먼저 StrategyPatternService 클래스를 보면 sp라는 객체는 인터페이스 객체인 StrategyPattern로 선언되었으며 StrategyPattern의 메서드인 dependency_injection()를 호출하고 있긴 하다. 그러나 객체 생성 과정에서 객체 sp StrategyPatternImpl 클래스를 주입시켜버림으로써 결과적으로 객체 sp StrategyPatternImpl dependency_injection()이란 메서드를 호출해버리고 말았다는 것이다.

 

그러므로 위에서 말했듯이 당신은 인터페이스의 메서드만 이용하더라도 위와같이 구현부는 나중에 주입을 통해 해결하므로 획기적인 분업과 동시에 구현 클래스를 쉽게 교체할 수 있다는 장점을 얻게 된다. 물론 스프링은 위의 이미지와 같이 단순한 방식으로 주입하진 않는다. 주입 방식에만 클래스 형태와 XML형태 2가지가 있으며 그 세부적으로도 어마어마하게 많은 방식으로 DI를 할 수 있다.

 

가끔 스프링을 쓰다보면 이런 다양한 방식이 진짜 편리와 우수한 기능을 위해서인지… 아니면 일부러 사용자를 헷갈리게 하려는 건지 분간이 안갈 때가 종종 있다. (개인적으로 로드 존슨이 프로그래머들을 편집증으로 몰아가기 위해 꾸민 음모가 아닌가 싶다…)

 

여하튼 IoC/DI의 개념을 요약하자면 정신나간듯 언제 사용될 지도 모르는 코드를 쳐대면서(IoC) 동시에 사용하고 있는 코드가 뭔지도 모르면서 일단 갖다 쓰는(DI) 획기적이고 진보적인 프로그래밍 작성방식이라 이해하면 되겠다.

 

 

서비스 추상화란?

 

솔직히 지금 DI를 설명하면서 서비스 추상화에 대한 부분까지 함께 설명해버렸다. 간략하게 개념에 대해서만 설명하자면 토비의 스프링의 일부분을 발췌하는 것이 좋을 듯 싶다.

 

추상화란 하위 시스템의 공통점을 뽑아내서 분리시키는 것을 말한다. 그렇게 하면 하위 시스템이 어떤 것인지 알지 못해도, 또는 하위 시스템이 바뀌더라도 일관된 방법으로 접근할 수가 있다.

 

그렇다. 우리는 위의 간단한 DI예제에서 StrategyPattern이란 인터페이스로 기능을 분리시킴으로서 하위시스템, 즉 클래스가 그 무엇으로 교체되더라도 해당 메서드는 반드시 존재할 것이란 보장을 받은 셈이다. 당신이 위의 모든 글을 읽고서도 아직 잘 이해가 가지 않는다면 지금 당장은 이러한 것을 과연 어떻게 구현해낼까에 대해 고민하지 않아도 된다. 사실 그것을 알아나가는 과정이 바로 스프링을 공부하는 과정이기 때문이다.

 

다만… DI예제의 과정, 즉 인터페이스를 구현하고 주입하는 과정이 이해가 가지 않는다면 당신은 자바에 대한 기본기가 매우 부족한 것이니 자바의 정석을 펼치고 객체지향개념부터 다시 필독하고 읽어보길 바란다.

 

'공부방 > Spring' 카테고리의 다른 글

교육5일차 정리  (0) 2013.03.08
교육 4일차 정리  (0) 2013.03.07
교육 3일차 정리  (0) 2013.03.06
교육 2일차 정리  (0) 2013.03.05
교육 1일차 정리  (0) 2013.03.04