본문 바로가기
Lecture/토비의 스프링 부트 - 이해와 원리

토비의 스프링 부트 - 독립 실행형 서블릿 애플리케이션

by Soono991 2023. 2. 2.

💡이 포스팅은 토비님의 인프런 강의인 토비의 스프링 부트 - 이해와 원리를 수강하고 학습한 내용을 정리한 포스팅입니다.

 

토비님의 강의를 수강하며 정리한 GitHub Repository 입니다.

 

GitHub - kiekk/inflearn-toby-spring-boot

Contribute to kiekk/inflearn-toby-spring-boot development by creating an account on GitHub.

github.com

 

이번 챕터에서는 Spring Boot의 기술을 사용하지 않고 Servlet을 사용하여 서블릿 컨테이너를 구성하는 방식을 학습합니다.

 

Spring에서는 기본적으로 DispatcherServlet이 있지만 Spring이 없던 Java EE 시절에는 직접 서블릿을 하나씩 등록하는 방식과, 이 방식을 Front Controller 패턴을 사용하여 조금 더 개선한 방식 총 2가지의 방식이 있습니다.

 

그래서 정리하자면 아래와 같은 순서로 기술이 발전된 것을 확인할 수 있습니다.

직접 서블릿 등록 → Front Controller 패턴 사용 → DispatcherServlet

 

이번 포스팅에서는 직접 서블릿을 등록하는 방식, Front Controller 패턴을 사용하는 방식의 특징과 단점들에 대해 정리해 보겠습니다.

 

직접 서블릿 등록

https://galid1.tistory.com/525

@WebServlet("/hello") <-- 요청 받을 url 작성
public class HelloServlet extends HttpServlet {
    public void init(ServletConfig config) throws ServletException {
        System.out.println("init() 실행");
    }

    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        System.out.println("service() 실행");
        // do business login
    }
}

 

서블릿을 직접 등록하는 방법은 위와 같이 @WebServlet + HttpServlet을 사용하는 방식이 있고

토비님이 강의에서 사용하신 방법이 있습니다. (❗자세한 내용은 강의 참고❗)

 

이 방식을 사용했을 때의 단점은 서블릿의 단위가 Class이기 때문에 새로운 요청(url)을 추가할 때마다 매번 서블릿을 추가해야 합니다.

 

따라서 각 요청(url) 별로 서블릿이 존재하기 때문에 관리해야 할 서블릿이 너무 많아지게 됩니다.

그리고 서블릿 또한 Class로 작성돼야 하기 때문에 naming에도 신경 써야 하는 단점이 있습니다.

 

마지막으로 같은 카테고리, 범주에 속한 요청(url)들이더라도 Class naming에 따라 다른 곳에 위치할 수 있기 때문에 관리도 매우 불편해집니다.

 

그래서 선배 개발자들은 이러한 단점들을 해결하기 위해 아래와 같은 고민을 하게 됩니다.

 

  • 단순히 요청에 따라 비즈니스 로직(Java Code)을 처리하는 경우가 많은데 이런 경우 굳이 서블릿일 필요가 있을까?
  • 같은 카테고리, 범주에 속한 요청들을 상위로 묶어서 관리할 수는 없을까?

위 고민들 끝에 나온 방법이 바로 Front Controller 패턴을 사용한 방식입니다.

 

Front Controller 패턴 사용

https://galid1.tistory.com/525

 

Front Controller는 말 그대로 앞에서 요청을 전부 처리할 수 있는 Servlet을 하나 만들고 Servlet에서 각 요청에 맞는 로직을 처리하도록 위임을 하는 방식입니다.

 

이렇게 되면 먼저 첫 번째 고민인 비즈니스 로직만 처리하는데 굳이 서블릿일 필요가 있을까? 가 해결됩니다.

Servlet은 오로지 FrontController 하나만 존재하며, 나머지는 모두 Java class이기 때문입니다.

 

그리고 두 번째 고민인 같은 카테고리, 범주에 속한 요청들을 하나의 묶음으로 관리할 수 있게 됩니다.

Front Controller는 여러 개 존재할 수 있습니다.

이를 이용해 같은 카테고리, 범주에 속한 요청들을 각각의 Front Controller로 생성하여 묶을 수 있습니다.

 

예를 들어

게시판의 경우 BoardFrontController

댓글의 경우 ReplyFrontController

주문의 경우 OrderFrontController...

 

이렇게 되면 개발자 입장에서 비슷한 요청들이 한 곳에 모여있기 때문에 관리도 수월해질뿐더러 불필요한 서블릿이 등록되는 것을 방지할 수 있게 됩니다.

 

그리고 이 방식을 사용했을 때 추가로 얻는 장점은 Servlet 영역(프레젠테이션 영역)과 Java Code 영역(비즈니스 영역)이 분리되어 Spring의 레이어드 아키텍처의 구조를 비슷하게나마 따라 할 수 있게 됩니다.

https://stdbc.tistory.com/20

 

하지만 Front Controller 패턴도 단점이 존재합니다.

  • FrontController에서 요청을 분기처리하는 로직이 하드 코딩으로 작성되어야 합니다.
  • 하나의 FrontController에서 처리할 요청이 많아질 경우 분기문이 길어져 가독성이 떨어집니다.

위와 같이 먼저 요청 url을 분석한 후 switch문이나 if-else문을 사용해 요청에 맞는 Controller를 찾아 요청을 위임해야 합니다.

 

이렇게 요청에 해당하는 Controller를 일일이 하드코딩으로 작성해 놔야 하기 때문에, 오타의 위험도 있을뿐더러 실수로 Controller는 만들었으나 요청 분기문에 추가를 하지 않는 경우도 발생할 수 있습니다.

 

그래서 Spring에서는 Front Controller 패턴 + Spring 기술을 이용해 DispatcherServlet을 만들었는데, 이 부분은 다음 챕터에서 정리해 보겠습니다.

 

하드 코딩보다는 Enum 사용

어떤 변수의 값이나 property의 key 값의 경우 단순히 리터럴 값으로 하드 코딩 하는 경우가 있습니다.

 

위 코드는 토비님 강의 코드를 일부 발췌한 것인데, 숙련된 개발자라면 메서드 이름만 보고서도 매개변수의 값들이 어떤 의미를 가지는지 쉽게 파악할 수 있을 것입니다.

 

하지만 그렇지 않은 경우 각각의 값들 200, Content-Type, text/plain이 어떤 의미를 가지는지 파악하기 쉽지 않습니다.

또한 여기서도 개발자의 오타가 발생할 수 있기 때문에 이런 경우에는 직접 값들을 하드 코딩하는 것보다는 Enum을 사용하는 것이 훨씬 좋습니다.

 

HttpStatus, HttpHeaders, MediaType 등과 같은 Enum은 친절하게 Spring에서 이미 제공하는 Enum들이며 우리가 사용하고자 했던 값들이 전부 Enum으로 정리되어 있습니다.

 

200 → HttpStatus.OK.value()
Content-Type → HttpHeaders.CONTENT_TYPE
text/plain → MediaType.TEXT_PLAIN_VALUE

 

이런 점을 기억하여 개발시 값들을 하드코딩하는 것이 아니라 직접 Custom Enum을 작성하여 관리하는 습관을 들이는 것이 좋습니다.

 

번외

Spring없이 직접 DispatcherServlet을 구현해 본 코드를 공유드립니다.

 

다음 챕터인 독립 실행형 스프링 애플리케이션에서 DispatcherServlet을 사용해 서블릿 컨테이너를 구성하는데

사실 DispatcherServlet을 잘 몰라도 학습하는데 큰 어려움은 없으나, DispatcherServlet의 동작 방식이나 내부 구현이 궁금하신 분들이 있다면 참고하시면 좋을 것 같습니다.

 

Spring의 DispatcherServlet을 완벽하게 구현하지는 못하고 간략하게 구현했기 때문에 DispatcherServlet을 모르시는 분들은 대충 이런 느낌으로 만들어졌구나라는 느낌으로, 이미 DispatcherServlet을 아는 분들은 복습의 느낌으로 보시면 좋을 것 같습니다.

 

GitHub - kiekk/make-dispatcher-servlet

Contribute to kiekk/make-dispatcher-servlet development by creating an account on GitHub.

github.com

 

댓글