서블릿

HyeonWoo·2021년 3월 3일
0

스프링 & JPA

목록 보기
30/34
post-thumbnail

서블릿

클라이언트의 요청을 처리하고, 그 결과를 반환하는 Servlet 클래스의 구현 규칙을 지킨 자바 웹 프로그래밍 기술

  • 클라이언트의 요청에 대해 동적으로 작동하는 웹 어플리케이션 컴포넌트
  • html을 사용하여 요청에 응답한다.
  • Java 쓰레드를 이용하여 동작한다.
  • MVC 패턴에서 컨트롤러로 이용된다.
  • HTTP 프로토콜 서비스를 지원하는 javax.servlet.http.HttpServlet 클래스를 상속받는다.
  • UDP보다 처리 속도가 느리다.
  • HTML 변경 시 서블릿을 재컴파일해야 하는 단점이 있다.

서블릿 컨테이너란?

서블릿 컨테이너는 개발자가 웹서버와 통신하기 위한 복잡한 일들(소켓 생성, 특정 포트 리스닝, 스트림 생성 등)을 할 필요가 없게 해준다. 컨테이너는 서블릿의 생성부터 소멸까지 일련의 과정을 관리한다. 서블릿 컨테이너는 요청이 들어올 때마다 새로운 자바 쓰레드를 만든다. 서블릿 컨테이너의 대표적인 예로는 Tomcat(WAS)이 있다.

역할

  • 웹서버와의 통신 지원

    • 서블릿 컨테이너는 서블릿과 웹서버가 손쉽게 통신할 수 있게 해준다 일반적으로 우리는 소켓을 만들고 listen, accept 등을 해야하지만 서블릿 컨테이너는 이러한 기능을 API로 제공하여 복잡한 과정을 생략할 수 있게 해줍니다. 그래서 개발자가 서블릿에 구현해야 할 비즈니스 로직에 대해서만 초점을 두게끔 도와줍니다.
  • 서블릿 생명주기 관리

    • 서블릿 컨테이너는 서블릿의 탄생과 죽음을 관리합니다. 서블릿 클래스를 로딩하여 인스턴스화하고, 초기화 메소드를 호출하고, 요청이 들어오면 적절한 서블릿 메소드를 호출한다. 또한 서블릿이 생명을 다 한 순간에는 적절하게 Garbage Collection(가비지 컬렉션)을 진행하여 편의를 제공한다.
  • 멀티쓰레드 지원 및 관리

    • 서블릿 컨테이너는 요청이 올 때 마다 새로운 자바 쓰레드를 하나 생성하는데, HTTP 서비스 메소드를 실행하고 나면, 쓰레드는 자동으로 죽게된다. 원래는 쓰레드를 관리해야 하지만 서버가 다중 쓰레드를 생성 및 운영해주니 쓰레드의 안정성에 대해서는 걱정하지 않아도 된다.
  • 선언적인 보안 관리

    • 서블릿 컨테이너를 사용하면 개발자는 보안에 관련된 내용을 서블릿 또는 자바 클래스에 구현해 놓지 않아도 된다. 일반적으로 보안관리는 XML 배포 서술자에 다가 기록하므로, 보안에 대한 수정할 일이 생겨도 자바 소스 코드를 수정하여 다시 컴파일 하지 않아도 보안관리가 가능하다.

서블릿 동작과정

서블릿 생명주기


1. 클라이언트의 요청이 들어오면 컨테이너는 해당 서블릿이 메모리에 있는지 확인하고, 없을 경우 init() 메소드를 호출하여 적재한다. init()메소드는 처음 한번만 실행되기 때문에, 서블릿의 쓰레드에서 공통적으로 사용해야하는 것이 있다면 오버라이딩하여 구현된다. 실행 중 서블릿이 변경될 경우, 기존 서블릿을 파괴하고 init()을 통해 새로운 내용을 다시 메모리에 적재한다.

  1. init()이 호출된 후 클라이언트의 요청에 따라서 service()메소드를 통해 요청에 대한 응답이 doGet(), doPost()로 분기된다. 이때 서블릿 컨테이너가 클라이언트의 요청이 오면 가장 먼저 처리하는 과정으로 생성된 HttpServletRequest, HttpServletResponse에 의해 request와 response객체가 제공된다.

  2. 컨테이너가 서블릿에 종료 요청을 하면 destroy() 메소드가 호출되는데 마찬가지로 한번만 실행되며, 종료시 처리해야하는 작업들은 destroy()메소드를 오버라이딩하여 구현하면 된다.

톰캣의 서블릿 관리

  • 서블릿 객체를 생성하고 초기화하는 작업은 비용이 많은 작업이므로, 다음에 또 요청이 올 때를 대비하여 이미 생성된 서블릿 객체는 메모리에 남겨둡니다.

  • 톰캣이 종료되기 전이나 reload 전에 모든 서블릿을 제거하게 된다.

  • 이렇게 톰캣은 자원을 아끼면서 서블릿을 사용하고 있음.

개발자도 자원을 효과적으로 사용하기 위해서는 서블릿의 생명 주기를 알아야 한다. 이에 대한 방법으로는 초기화하는데 호출되는 init() 메서드를 활용한다. 즉, 요청이 매 번 똑같은 로직을 거쳐서 똑같은 결과를 산출하는 작업은 딱 한번만 수행 되도록 init() 에서 처리하는 것이다.

Dispatcher-Servlet이란?

개념 : 클라이언트로부터 어떠한 요청이 들어오면 서블릿 컨테이너가 요청을 받는다. 이 때 제일 앞에서 서버로 들어오는 요청을 처리하는 프론트 컨트롤러를 Dispatcher - Servlet이라고 한다.
공통작업에 대한 처리는 Dispatcher-Servlet에서 이루어지지만 세부적인 작업 내용은 해당되는 컨트롤러에 위임하여 처리한다.

특징

  • Dispatcher-Servlet이 등장함에 따라 Spring MVC의 web.xml의 역할이 축소되었다.

  • 기존에는 모든 서블릿에 대해 URL 매핑을 활용하기 위해서 web.xml에 모두 등록해주어야만 했다.

  • Dispatcher-Servlet이 들어오는 모든 요청을 핸들링해주면서 작업을 상당히 편리하게 할 수 있게 되었다.

  • Dispatcher-Servelt이 요청들을 컨트롤러로 넘겨주는 것은 편해보이지만, 한가지 문제점이 있다. 이미지나 HTML을 불러오는 요청마저 모두 컨트롤러로 넘겨버린다는 것이다. 심지어 JS나 CSS파일에 대한 요청 모두 Dispatcher-Servlet이 가져가기 때문에 자원 호출이 제대로 이루어지지 않는다.

  • Spring은 이에 대한 해결책으로 <mvc:resources/>를 이용할 수 있도록 내놓았다. 만약 Dispatcher-Servlet에서 해당 요청에 대한 컨트롤러를 찾을 수 없는 경우에, 2차적으로 설정된 경로에서 요청을 탐색하여 자원을 호출할 수 있도록 한다.


참고자료
https://medium.com/@fntldpf12/%EC%84%9C%EB%B8%94%EB%A6%BF-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88%EB%9E%80-d5095e661a85,
https://victorydntmd.tistory.com/154,
https://mangkyu.tistory.com/14

profile
학습 정리, 자기 개발을 위한 블로그

0개의 댓글