티스토리 뷰
[ Spring Study ]
스프링에 대해 전반적인 구조 및 흐름에 대해서 몰랐던 부분이 너무나 많다는 걸 깨닫게 되는 순간..
한번쯤 어디선가 읽어봤던 내용들에 대해 개념을 제대로 알고자 스프링에 대해 처음부터 공부하게 되었다.
경보 속도로 공부해 보자!!!
서블릿과 서블릿 컨테이너에 대해 알아보기 이전에, 간단하게 웹서버와 웹애플리케이션 서버를 짚고 넘어가자.
Web Server는 HTTP 기반으로 동작하는 서버로, 정적 리소스를 제공하며 대표적으로 Apache, Nginx 가 있다.
Web Application Server는 HTTP 기반으로 동작하는 서버로, 정적 리소스를 포함하여 동적 리소스를 제공하며 대표적으로 Tomcat, Jetty 가 있다.
왜 서버에 대해서 이야기를 했냐면, 웹 애플리케이션이 서블릿 컨테이너를 포함하고 있기 때문이다.
참고) 사람들의 의견은 다 제각각이지만, 보통 웹 애플리케이션을 서블릿 컨테이너라고 부른다고 한다.
하지만 일부 웹 애플리케이션 서버는 JSP, Spring MVC를 실행할 수도 있기 때문에 딱 서블릿 컨테이너라고 말하기엔 음..
서블릿 외에 다른 기능을 수행하기 때문에 서블릿 컨테이너를 포함한다 (Servlet Container In WAS)라고 생각하면 좋다.
* 스프링 부트에서는 톰캣을 내장하고 있으며 톰캣은 서블릿 컨테이너로 이루어져 있다!
.
.
자 그럼 서블릿과 서블릿 컨테이너에 대해서 알아보자.
서블릿은 동적인 웹 페이지를 만들기 위해 사용되는 자바 기반의 프로그램이다.
웹 애플리케이션을 만들려면 request, response 메시지 및 비즈니스 로직은 물론이고 다양한 규칙 (HTTP 메서드, Header 및 Body 내용) 이 존재하는데, 이러한 내용을 전부 다 구현하려면 난 블랙홀에 빠지는 게 더 빠를 것이다. 🤦♂️
그래서 서블릿이 등장하게 되었으며, 요청과 응답을 가지고 비즈니스 로직 실행만 할 수 있도록 도와주는 기술이라고 생각하자.
서블릿을 한번 생성해 보자.
@WebServlet(name = "phoneFormServlet", urlPatterns = "/servlet/phone/new-form")
public class PhoneFormServlet extends HttpServlet {
@Override
public void init() throws ServletException {
super.init();
log.info("servlet init !");
}
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) {
log.info("servlet service invoked!");
//애플리케이션 로직
}
@Override
public void destroy() {
super.destroy();
log.info("servlet destroy !");
}
}
// /servlet/phone/new-form 요청 세번 시 실행 로그
2022-12-26 23:42:00.219 INFO 58271 --- [nio-8080-exec-1] c.e.s.web.servlet.PhoneFormServlet : servlet init ! //초기화 한번 진행됨
2022-12-26 23:42:00.229 INFO 58271 --- [nio-8080-exec-1] c.e.s.web.servlet.PhoneFormServlet : servlet called!
2022-12-26 23:42:04.679 INFO 58271 --- [nio-8080-exec-2] c.e.s.web.servlet.PhoneFormServlet : servlet called!
2022-12-26 23:42:07.064 INFO 58271 --- [nio-8080-exec-3] c.e.s.web.servlet.PhoneFormServlet : servlet called!
* 서블릿을 생성할 때 HttpServlet 클래스를 상속받아야 한다.
* url pattern 이 /servlet/phone/new-form의 URL이 호출되면 해당 서블릿 코드가 실행이 된다.
* 실제 비즈니스 로직은 service 함수를 통해서 진행된다.
service 함수의 매개변수로 있는 HttpServletRequest 객체를 통해 클라이언트의 요청 정보를 편리하게 사용할 수 있으며 HttpServletResponse 객체를 사용하여 클라이언트에게 보낼 응답 정보를 생성할 수 있다.
(추가 참고 - 지금 내가 만든 서블릿의 service 함수는 로그만 출력하게 두었지만, HttpServlet의 service 함수는 HTTP 메서드에 따라 실행되는 비즈니스 로직이 다 다르다. - 자세한 내용은 HttpServlet 클래스의 service 함수를 확인해보면 알게 된다.)
.
실행 로그를 확인해보면 init 로그는 한번 service 로그는 세 번이 출력된 것을 알 수 있는데, 이는 서블릿 컨테이너 알아볼 때 다루기로 하자.
서블릿도 생성해보고 동작도 해봤는데 대체 서블릿은 어떻게 클라이언트의 요청을 받을 수 있는 것일까?
그건 바로 서블릿 컨테이너를 통해 진행된다.
서블릿 컨테이너는 서블릿 객체를 생성, 초기화, 호출, 종료하는 서블릿의 생명 주기를 관리하며, 클라이언트에서 요청이 들어왔을 때 컨테이너는 HttpServletRequest, HttpServletResponse 두 객체를 생성하고 동적인 페이지를 생성하여 응답한다.
서블릿 컨테이너가 지원하는 기능
1. 서블릿 생명주기 관리
서블릿 객체는 싱글톤으로 관리한다. (따라서 서블릿을 생성할 때 멤버 변수를 사용할 때 주의해야 한다.)
✔️ init() - 초기화
서블릿이 처음으로 요청될 때 초기화가 한번 진행되며, 초기화된 서블릿은 싱글톤으로 관리된다.
(* 싱글톤으로 관리되기 때문에 서블릿 생성할 때 멤버 변수를 사용할 때 주의해야 한다!)
따라서, 다음에 같은 서블릿이 요청되면 초기화가 다시 일어나는 것이 아니라 기존에 있던 서블릿을 호출하게 된다.
-> 그래서 위에 서블릿 생성하고 동작 확인해 봤을 때 init 로그가 한 번만 출력된 것이다.
✔️ service() - 호출
Servlet 인터페이스를 구현한 HttpServlet 클래스의 doGet, doPost와 같은 메서드가 호출된다.
(HTTP Method에 따라서 호출되는 함수가 다르다!)
✔️ distory() - 종료
서블릿 컨테이너는 더 이상 사용되지 않는 서블릿 인스턴스가 삭제되기 전에 destroy를 한번 실행한다.
//javax.servlet.Servlet
public interface Servlet {
public void init(ServletConfig config) throws ServletException; //초기화
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException; //호출
public void destroy(); //종료
}
2. 멀티스레딩 관리
서블릿 컨테이너는 새로운 요청이 들어오면 스레드를 생성해서 서블릿을 호출(One Thread Per Request)한다.
☝ 만약 요청마다 스레드를 생성하면 무한대까지 생성할 수 있는데, 그렇게 되면 서버가 죽지 않을까?
그렇지만 이 문제를 해결하기 위해서 스레드 풀(Thread Pool) 이 지원된다.
스레드 풀에 미리 스레드를 생성하고, 요청이 오면 스레드 풀에서 스레드를 빌려서 쓰고 반납하는 과정을 거친다.
(* tomcat 기준, Thread Pool의 Thred의 기본 개수는 200개이다.)
만약 Thread Pool의 제한 개수를 넘어 요청이 들어온다고 하면, 스레드 대기 및 거절할 수 있도록 처리할 수 있다.
(Thread 대기 및 거절에 대한 내용은 나중에 자세하게 확인해보도록 하자.)
3. 통신 지원
4. 보안관리
서블릿 컨테이너 동작 방식

1. 웹 브라우저에서 요청한다.
2. WAS 서버에서 요청 메시지를 기반으로 request, response 객체를 만들어 서블릿 객체를 호출한다.
☝ 이때, 서블릿 컨테이너에 서블릿이 존재하지 않으면 객체를 초기화하며 서블릿이 존재하면 해당 서블릿을 호출한다.
3. WAS는 response 객체에 담겨있는 내용으로 HTTP 응답 정보를 생성한다.
참고
스프링 MVC 1편 - 김영한
https://coding-factory.tistory.com/742
https://www.javatpoint.com/life-cycle-of-a-servlet
https://www.programcreek.com/2013/04/what-is-servlet-container/
'Framework > Spring' 카테고리의 다른 글
Spring Security 의 첫 걸음 (0) | 2024.11.17 |
---|---|
auto-configuration에 대하여 (0) | 2024.10.23 |
[Spring] DispatcherServelt (Feat. Front Controller) (0) | 2022.12.16 |
[Spring] 순환 참조 (0) | 2022.12.13 |
[JPA] N + 1 문제 (0) | 2022.12.05 |
- Total
- Today
- Yesterday
- 정적변수
- 오블완
- 인스턴스변수
- spring boot
- fail-fast
- syncronized
- HashMap
- Security
- 고정 세션
- Caching
- 다중화
- HashSet
- Spring
- fail-safe
- nosql
- nginx
- 인터페이스
- 로드 밸런서
- @conditional
- Hash
- Sticky Session
- 추상클래스
- AutoConfiguration
- Red-Black Tree
- JPA
- object
- Load Balancer
- java
- 티스토리챌린지
- 자동구성
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |