오늘 현대차 그룹사 소속인 지아이티에서 면접을 보던 중 기본적인 질문인 DI에 대해서 물어보았다.
면접관 : 기본적인 질문 하나 할게요. DI를 왜 쓰는지 말해주실 수 있나요?
나 : Dependency injection이라 하고 객체를 new 키워드를 적지 않고 생성해주기 위해 사용합니다.
면접관 : (흐음...) 그럼 DI가 정확히 무엇인지 말해주실 수 있나요?
나 : 잘 모르겠습니다...
답을 잘못한거 같아서 속으로 이불킥 몇 번 했다. DI에 대해 분명 몇 번이고 보고 정리를 했다고 생각했는데 아직도 잘 모르다니! 다음에도 이렇게 답하거나 경력이 됐을 때도 신입에게 말 못하면 너무 쪽팔릴 것 같아 아예 이번 기회에 글로 정리해보려고 한다.
사실 전에 면접봤던 회사에서도 DI에 대해 물어봤었고 관련 글로 정리했었다. 그래서 new 키워드 대신 객체를 생성해준다는 답변이라도 할 수 있었던 것 같다.
=> 위 답변은 데이터베이스 관련 직군 기술면접 기출문제 - k9e4h님 글을 참조했었다.
여기에서 키워드를 뽑아내자면, applicationContext.xml, 의존객체, 의존관계라는 키워드들이 있는데 이 키워드를 잘 이해를 못했던 것 같다. 그럼 차근차근 키워드 이해부터 시작하면 DI에 대한 정확히 이해할 수 있을 것이다.
만들었던 프로젝트를 확인했을 때, applicationContext.xml 이라는 녀석 자체가 없었다.
대신, servlet-context, root-context가 있다. 그리고 난 이 둘은 안다.
그럼, applicationContext.xml란 녀석은 누구일까?
ApplicationContext context = new ClassPathXmlApplicationContext(xml파일명);
아무 것도 없었다. 즉, ApplicationContext.xml은 ApplicationContext라는 클래스 객체가 xml이 매개변수로 필요하기 때문에 대충 이름 지어준 xml 파일에 불과했다.
그리고 Spring Legacy Project로 생성해줬을 땐 만들 필요조차 없다.
추측하기로는 web.xml에서 web-app이 version 2.5일 때는 applicationContext도 자동생성이 됐는데 version 3.1로 업글되면서 사라져서 남은 잔재가 아닐까 추측한다.
스프링 컨테이너에 대한 요약 글을 참조했다.
ApplicationContext는 Bean 객체를 생성하고 관리하는 기능을 가지고 있다.
뿐만 아니라 트랜잭션 관리, 메시지 기반의 다국어 처리, AOP 처리등등 DI(Dependency Injection) 과 Ioc(Inverse of Conversion) 외에도 많은 부분을 지원하고 있다.
Spring 예제를 연습할 때, DI, AOP 등을 연습할 때 쓸 수 있겠다. 즉, DI에서 ApplicationContext.xml을 쓴다는 건 포괄적인 설명은 아니라고 볼 수 있겠다.
Spring Legacy Project만 만들어도 자동으로 xml 파일들을 생성해주니까!
의존성이란 말에 집중할 필요가 있다. has - a 관계인 클래스가 의존성을 가진다고 생각하면 된다.
아주 간단하게 코딩하면 이런 상태다. 이런 형태를 Person has a Hand라고 한다. 둘은 의존관계이자 Person 클래스가 Hand 클래스에 의존한다. 라고 말할 수 있겠다.
여기서 문제는 Hand 클래스를 상속받는 LeftHand, RightHand 를 사용하게 될 때이다. Person도 변경되어야한다. 의존성이 생기게 되면 꼭 변경할 필요가 없는데도 변경할 필요성이 생긴다.
나는 한 때는 왼쪽손, 어떨 때는 오른손을 흔들고 싶은데, 그럴 때마다 Person까지 와서 변경해줘야한다. 하지만, 의존성을 주입하게 되면 다음과 같은 코딩이 가능해진다.
이제 왼손과 오른손을 외부 설정파일만 바꿔줘도 다른 손을 흔들 수 있게 되었다.
결론
- DI, 의존성 주입은 필요한 객체를 직접 생성하는 것이 아닌 외부 XML로부터 필요한 객체를 받아서 사용하는 것이다.
- 이를 통해 클래스 간의 결합도를 줄이고 코드 재활용성을 높여준다.
이 정도면 누가 DI에 대해 쿡 찔러도 튀어나올 만큼 공부가 잘 된 것 같아 기쁘다. DI 가 뭐야?! 묻는다면 "코드에서 객체를 직접 생성해주는게 아니라, 외부 설정파일에서 필요한 객체를 받습니다. 이를 통해 클래스 간의 결합도를 낮출 수 있습니다. 의존성을 낮춘다고도 하죠." 라고 답변하겠다.
결합도가 뭔가요? 라고 물으면... has-a 관계부터 의존성에 대해 설명하면 되겠다.
Spring Framework Documentation - Spring
[Spring Framework] Application Context 사용하기 -_tech님
[Spring MVC] 스프링 컨테이너에 대한 요약 - ehdrms2034님
[DI] Dependency Injection이란 무엇일까? - wlsdud2194님