Rath World Notes by Jang-Ho Hwang

15Sep/09Off

Spring framework을 공부하며: 무엇을 dependency로 규정해야 할까?

Posted by Jang-Ho Hwang

도대체 이제서야 Spring 을 공부하는 이유가 뭡니까?

런던에 도착한지 7주가 되어 갑니다. 아무리 본인의 취업의지가 희박하여 취업활동을 거의 진행하지 않았다 하더라도 7주 정도가 지나면, 월 고정 지출금액이 500만원이 넘는 런던 생활을 견딜 배짱이 조금씩 줄어듭니다. 리쿠르팅 사이트들을 면밀히 분석해본 결과 Spring이 너무 많더군요. 그래서 시작했습니다.

무슨 책으로 공부하고 있나요?

Amazon Kindle Store 에서 구입한 Spring Recipes를 보고 있습니다. 원래 Spring에는 전혀 관심이 없었는데 유독 이 책만은 제 흥미를 떨어트리지 않고 있습니다. 현재 16% 읽었습니다. (Kindle이 그렇게 표시해주네요)

소감 한 말씀

수년간 스프링을 건드리지 않았지만, 그래도 지인들께서는 스프링을 많이 쓰시기 때문에 주워들은 것들이 있었습니다. DI와 IoC container가 핵심이라는 말이였는데요. 스프링을 자세히 살펴보기전에는 Dependency Injection이 머 대단한 기술이라고 저렇게 호들갑인가.. 했었는데 Spring IoC container가 훌륭한 것이였더라고요. 기본 컨셉만을 지키는 IoC container를 만들라면 저 혼자서도 하루만에 만들어볼 수 있겠지만, Spring IoC container가 제공하는 feature set을 살펴보고 있노라니 엄두가 나지 않더라고요.

이녀석 어디에 써야 할까

IoC container의 basic feature들을 책을 통해 습득하고, 감 잡았다 싶어 기존 프로젝트에 spring을 적용하며 훈련해보자는 생각으로 얼마전에 만든 미투 구글리더 서버에 spring을 도입해보기로 결정했습니다.

그런데.. 막상 도입하려고 하니 무엇을 dependency로 규정해야할지가 문제였습니다. 미투 구글리더 서버는 POJO 소스코드까지 다 합쳐봐야 1,000라인이 안됩니다. 사용하는 library 들은  httpcomponents, commons-dbcp, slf4j-with-log4j, me2api-java 가 전부입니다.

이용중인 라이브러리들을 의존성이라고 규정해볼까요?

HttpComponents는 의존성이라고 규정하기 어렵습니다. 미투 구글리더 서버의 핵심이 http 요청을 최소의 cpu, i/o 부하로 *잘* 핸들링 하는 것이기 때문입니다. 수많은 사용자들의 구글리더 atompub url을 핸들링 하기 위해 HttpComponents에 최적화된 코드들이 몇 개 들어있는데.. 이것을 의존성으로 가정한다면 프로젝트 자체의 정체성이 모호해지기 때문입니다. 그래서 HttpComponents는 그대로 두기로 했습니다.

DBCP는 의존성이라고 규정하기 대단히 쉽습니다. 그저 빼버리면 그만입니다. 안그래도 commons-dbcp가 500KB가 넘는 commons-collections에 의존성이 걸려있어서 언제 퇴출시켜야할지 눈여겨 보고 있었던 놈이기 때문입니다.

slf4j는 많은 로깅 라이브러리들의 의존성을 날려버리기 위해  log4j, commons-logging, java.util.logging 을 facade로 추상화한 녀석입니다. 그런데 요녀석을 의존성으로 규정하자니.. 어불성설입니다. 한가지, slf4j ext의 Profiler 클래스를  쓰고 있는데, 이 Profiler는 dependency로 볼 수 있겠네요.

me2day-api. 세상에, 제품 이름이 미투 구글리더인데 여기서 미투가 의존성이라니.. 이게 말이 되는건가요? ㅋㅋㅋㅋㅋㅋ. 하지만 잠시 진지하게 생각해봅니다. 미투 구글리더 서버는 대부분의 cpu와 i/o 시간을 구글리더 피드 url을 긁고 분석하는데 사용합니다. 미투데이 API와 함께 하는 시간은 1%가 채 안됩니다. 아무리 제품의 정체성을 존중해준다고는 하지만 조금 아깝다는 생각이 듭니다. 미투 구글리더의 역할을 한줄로 요약하라고 하면, "신나게 지켜보다가 이벤트가 발생하면 sns에 쏜다" 입니다. 여기서 "sns에 쏜다"를 인터페이스로 규정짓고 미투데이를 의존성으로 가정한다면 실제 구현 인스턴스에는 twitter도 있을 수 있고 facebook도 있을 수 있습니다. 이것 참 해볼만한 일입니다.

구글리더. 이것 역시 제품 이름의 66.6%를 차지하는 무게 있는 녀석이긴 하지만, 구글리더와 함께 하는 작업을 인터페이스화 하면 "피딩 문서를 노려보고 있다가, 업데이트가 일어났음이 감지되면, SNS 사이트에 넘길 헤딩과 사용자의 의견을 뽑아낸다" 가 됩니다. 그것이 구글리더가 됐든, Facebook Share가 될지는 상관없습니다. 하지만 미투데이 api와 마찬가지로, 제품 스펙을 늘려서 DI를 적용하려니 적지 않게 찝찝한 기분이 느껴집니다.

configuration. 미투 구글리더의 config.properties 에는 3개의 정보가 있습니다. 피드 polling thread executor에게 줄 휴식시간 값, 미투데이 APP Key, 그리고 백엔드 RDBMS의 설정입니다. 이미 파일로 잘 떨어져 나와있어서 의존성이라 규정하기는 어렵습니다만, 훈련용으로 가볍게 시작하기에는 가장 적절한 부분이라고 생각합니다. Config bean을 정의하고 각 config item 들에 대해 적절한 setter를 만들어주면 바로 해결됩니다. 연습하기에는 아주 적절하지만 real world에는 적절치 못한 예로 보입니다.

마치며

레거시 앱을 보며 DI를 어디에 적용하는 게 좋을까.. 하는 접근은 단연 옳지 않습니다. 이것은 그저 훈련을 위한 것이지요. 그보다는 이 의존성을 어떻게 없애야할까- 할 때나, 개발 미팅 중 "그렇게 되면 어디어디에 의존성이 걸리잖아요?" 라고 말하게 되는 부분을 깔끔히 해결해주는 고마운 프레임워크라고 보는 것이 옳바른 듯 합니다. 조금 더 나아가 Spring IoC container의 feature를 십분 활용하여, 평소에는 그것이 의존성이라고 생각도 못한 부분들에 대해 다시 한 번 생각할 수 있는 기회를 주는 현자 역할도 해준다는 생각이 드네요.

위에서 살펴본 것처럼 DI를 마구 적용하려고 하면 한도 끝도 없는 것 같습니다. 그러나 개발자에게 큰 경각심을 주는 부분은 프로젝트에 Spring IoC container의 DI를 적용하기로 하면 프로젝트 디자인이 '개발자의 순수 의지와는 상관없이 깔끔해진다'는 장점은 무시하지 못할 부분이라고 생각합니다.

이제 글을 그만 쓰고 생각을 행동에 옮길 시간입니다. 안녕히!