WAS에 억지 DI 시켜보기

김수환·2025년 7월 13일

was 구현기

목록 보기
6/11

DI 컨테이너가 필요하다고 느꼈다

톰캣처럼 동작하는 서블릿 기반 WAS를 구현해보면서, 자연스럽게 내부 구조에 대한 의문이 들기 시작했다.
톰캣은 잘 만들어진 소프트웨어고, 실제 현업에서도 수많은 트래픽을 안정적으로 처리한다. 그런데 구조를 따라 만들다 보니, 이런 생각이 들었다:

"톰캣은 내부 의존성을 전부 직접 생성 하면서 관리했을까?"

톰캣은 그렇게 하고 있었다.
서블릿 컨테이너, 디스패처, 매핑 객체들 간 의존성이 필요할 때마다 new로 생성하거나 세터로 주입하며 연결해 나간다.
DI 컨테이너 같은 건 없었다.


톰캣은 왜 DI를 쓰지 않을까?

톰캣은 어디까지나 Servlet 스펙을 구현한 WAS다.
HTTP 요청을 받아 서블릿을 실행하는 역할에 집중하며,
그 외의 객체 생성이나 의존성 관리는 개발자에게 맡긴다.

  • Its lightweight and efficient design makes it ideal for many Java web applications.
  • Tomcat servlet containers are meant to take care of multi-threading, http request handling and any other things related to non‑business logic, while you implement a servlet with your business logic to run inside the container.

즉, 아마 이런 철학이었다고 한다.

  • 플랫폼은 가볍고 범용적이어야 한다.
  • 애플리케이션 로직과 컴포넌트 관리는 외부에서 맡길 수 있도록 구조를 열어둔다.

실제로 톰캣은 Spring 같은 프레임워크와 함께 동작하는 걸 전제로 만들어져 있다.
그래서 DI는 처음부터 톰캣의 역할이 아니라고 보는 게 맞긴 하다.


혼자 든 의문..

직접 설계하다보니, WAS용 컴포넌트들도 생각보다 많은 의존성을 가지게 됐다.

  • StaticServeletStaticFileLoader와, PathResolver에 의존하고, 다른 컴포넌트가 추가되면 의존성이 복잡해 질것이라 생각한다.
  • 테스트나 확장성을 고려하면 각각을 하나하나 new 해서 묶는 것도 쉽지 않았다

개발할수록 불편함이 쌓일 것이고, 결국 다음과 같은 생각이 들었다:

이 부분은 Spring을 따라서 의존성을 주입해보자.

그래서 아주 단순한 DI 컨테이너를 만들었다.

현재 구조는 다음과 같이 구성되어 있다:

  • @Singleton을 붙인 클래스는 컨테이너가 하나만 만들어 관리한다
  • 생성자의 파라미터 타입을 읽어 의존 객체를 찾아 주입한다
  • 컴포넌트 목록은 initialize()를 통해 명시적으로 등록한다

아직 순환 참조 검증, 빈 라이프사이클 관리는 구현하지 못했다.
하지만 추후 확장하기 쉽게 만들어두었다고 생각한다.


잘 한 건지는 모르곘다..

톰캣이 DI 없이 설계한 걸 보면 내가 미처 이해하지 못한 설계 철학이나 운영상 이유가 있을 수도 있다.

최대한 lightweight하게 설계하려는 목적이었을 수도 있고, 의존성 주입보단 명시적 설정을 선호했을 수도 있다

또한, 내가 만든 DI는 아직 단순한 수준이라 실제로 톰캣 수준의 복잡한 구조에서는 분명 오류가 날 것 이다.


그래도 배운 게 있다

이 과정을 통해 하나는 확실히 느꼈다.

톰캣은 최소한의 플랫폼으로서의 철학을 따랐고, 나는 개발자의 관점에서 편리한 구성을 원해서 구현해봤다.

솔직히 잘 한 건지는 모르겠다..
분명 커지면 문제가 생길 수 도..?
하지만 고민해보고, 필요하다고 느낀 기능을 만들어봤다는 점에서 보람이 있었다.


나중에 이 DI 컨테이너를 더 발전시킬지, 아니면 다른 방식으로 갈지는 아직 모른다.
하지만 이번 경험을 통해, "왜 스프링이 나왔는가"에 대해 조금은 느낄 수 있었던 것 같다.

profile
hello human

0개의 댓글