스프링부트 동작원리
1. 스프링부트는 내장 톰캣을 가진다.
톰캣을 따로 설치할 필요 없이 바로 실행 가능하다.
socket통신에는 스레드의 이해가 필요하다.
socket: 콘센트, (전기 기구에서 플러그 등을) 꽂는 곳, (전구) 소켓, (다른 부분이 들어갈 수 있도록) 푹 들어간 곳, 구멍
소켓방식으로 연결되면 지속적인 연결로 인해 과부하가 일어날 수 있다.
http통신은 stateless 방식으로 하나의 요청에 하나의 응답이 끝나면 그 통신을 끊어버린다
→ (서버측에서는) 부하가 적다, 단, 기존에 요청했던 클라이언트가 재요청할시 동일한 클라이언트인지를 식별하지 못한다.
http는 확장자가 html인 문서를(파일) 전달하기 위해 만들어졌다, 문서전달의 목적으로 만들어진 http 통신
http는 운영체제가 가지고 있는 소켓이란 것을 이용해서 만들어졌다 → 소켓 통신기반으로 만들어진 http 통신
*** 소켓에 대하여 더 알아보기 위해 다른 유튜버 강의들을 들어보고 정리함
(프로토콜 스펙에서 정의한) 소켓이란, 어플리케이션 계층과 전송 계층 사이에 존재한다.
└ 인터넷이 발명되면서 함께 개발된 프로토콜 스펙은(TCP/IP stack) 4가지 계층으로 구성된다.
- 어플리케이션 계층(application layer)
- 전송 계층(transport layer)
- 인터넷 계층(internet layer)
- 링크 계층(link layer)
링크/인터넷/전송계층은 하드웨어/펌웨어,OS레벨에서 구현되고 관리된다 → 시스템
└ 네트워크 기능을 지원하기 위해 존재한다.
컴퓨터에 존재하는 어플리케이션들이 링크/인터넷/전송 계층이 지원하는
네트워크 기능을 사용해서 네트워크 서비스를 구현할 수 있게 된다.
반면 어플리케이션 계층은 네트워크 기능을 사용하는데 목적이 있으며
어플리케이션 레벨에서 구현되고 관리된다 → 어플리케이션
프로세스간 인터넷을 통해서 네트워크 통신을 한다면
인터넷 프로토콜을 통해서 데이터를 송수신할 수 있는데,
데이터의 유실이 발생할 수 있고, 데이터를 순서대로 받을 수 있을지 보장이 안되는,
인터넷 프로토콜의 단점을 보완하여 TCP 프로토콜이 탄생하게 되었다.
└ 프로세스 간의 통신에서는 데이터를 안정적으로 주고 받을 수 있는 프로토콜이 필요
소켓통신을 기반으로 http 통신규칙이 만들어졌고,
클라이언트가 웹 서버의 ip주소와 파일의 위치(url)를 요청하면,
웹 서버는 하나의 자원 요청에 하나의 자원 응답한 뒤 소켓통신이 끊긴다.
웹 서버는 정적인 파일(static 자원)을 응답해준다.
만약 클라이언트가 확장자가 jsp인 파일 또는 자바코드가 적힌 파일을 요청하면
웹 서버는 자바코드를 해석하지 못하기 때문에 톰캣에게 요청을 전달한다.
톰캣은 jsp파일 내에 존재하는 모든 자바코드를 컴파일하고
컴파일이 완료되면, 컴파일된 데이터를 html 문서에 덮어씌운다(html 문서를 생성함).
생성한 html문서를 톰캣은 웹 서버에 전달하고 웹 서버는 해당 문서를 클라이언트에 응답한다.
웹 서버는 요청한 파일을 응답해주고, 톰캣은(Web Application Server, WAS)
요청한 파일 중에자바코드가 요청이 되면, 그 자바코드를 컴파일한 후 html파일로 생성해서 돌려준다.
2. 서블릿 컨테이너
클라이언트가 요청하면, 해당 요청을 톰캣이 받고(서블릿 컨테이너)
그 요청이 최초 요청이면 객체를 생성하고, 최초 요청이 아니면 이미 생성되어 있는 객체를 재사용한다.
클라이언트 --- 요청 → 서블릿 컨테이너(톰캣) --- 최초 요청인가? --- 예 → 메모리 로딩 → 객체 생성 → init()
→ service(HttpServletRequest, HttpServletResponse)
- 최초 요청이 아닐경우 --- 이미 생성된 객체 재사용 ┘
정적인 파일(.html, .css, .png 등) 관련 요청이 들어오면 톰캣이 아닌 웹 서버가 작동한다.
스프링의 경우 식별자를 통해서 접근하는 방식이기 때문에 .html, .css, .png와 같은 파일을 요청할 수 없고,
└ uri
(스프링 기반 프로젝트인 경우 자원에 직접 접근하는 방식을 막아놓았다)
식별자를 통해서 요청해야 하기 때문에 특정한 파일 요청을 할 수 없고,
요청시에는 무조건 자바코드를 거쳐야 하기 때문에 웹 서버는 무조건 톰캣에게 요청을 넘기게 된다.
스프링 프로젝트의 경우 클라이언트가 직접적인 자원을 요청하지 못하도록 막아놓았다.
url이 아닌 식별자를 통해서 접근하는 방식인 uri로 요청하도록 설정, uri 방식은
무조건 자바 코드를 해석해야 하기에 웹 서버는 톰캣에게 요청을 넘기고,
톰캣은(서블릿 컨테이너) 해당 요청을 처리한다.
클라이언트로부터 자바 코드 관련 요청이 웹 서버에 들어왔을 경우
웹 서버는 톰캣에 요청을 전달한다. 최초 요청인 경우 톰캣은(서블릿 컨테이너)
1. 서블릿 객체를 생성하고
2. init() 메서드를 호출, 초기화한 후 --- service() 메서드 호출 직전에 스레드를 만들고,
3. service() 메서드를 실행하여 요청 방식을 확인한다(GET, POST, PUT, DELETE 등)
4. 요청 방식이 GET이라면 get() 메서드가 실행된다.
최초 요청이 아닌 경우
기존에 생성된 서블릿 객체를 재사용한다, init() 메서드 호출 생략
스레드를 하나 만들어서 service() 메서드를 호출한다.
요청 방식에 맞는 메서드를 호출한다(ex. get(), post() ...)
*** 서블릿 객체는 하나지만 그 객체가 지니는 메서드를 여러 번 호출할 수 있는 이유
new 연산자와 생성자로 만들어진 객체는 힙 메모리에 쌓이고,
힙 메모리에 존재하는 객체가 지니는 메서드 호출시 해당 메서드는
stack 메모리에서 각 독립적인 공간에서 실행된다. 톰캣에서 스레드의 수를 설정할 수 있고,
하나의 요청에 하나의 응답이 이루어지면 스레드는 종료된다. 서블릿 객체와 스레드들은 재사용된다.
3. web.xml
- ServletContext의 초기 파라미터
- Session의 유효시간 설정, session은 인증을 통해 비롯된다.
인증을 통해 생겨난 세션에 유효기간이 설정되어 있다면 해당 기간이 끝날 때 세션은 만료된다.
- Servlet/JSP에 대한 정의, Servlet/JSP 매핑 → Servlet/JSP 매핑시 두 가지 방법이 있다.
첫 번째 방법은 web.xml 파일에 직접 매핑, 두 번째 방법은 @WebServlet 어노테이션 사용이다.
첫 번째 방법을 사용할 경우 모든 클래스에 매핑을 적용시키기에 코드가 너무 복잡하기 때문에
FrontController 패턴을 사용하게 되었다.
- Mime Type 매핑: 클라이언트 요청이 서버에 들어왔을 때,
해당 요청의 타입이 무엇인지 알고 요청의 타입에 맞게 가공을 거쳐야 한다.
- Welcome File List
- ErrorPages처리
- 리스너/필터 처리
- 보안
하나의 서블릿 객체는 객체는 heap 메모리 공간에 존재하고, 그 객체가 지닌 메서드 호출시 stack 메모리 공간에 독립적인 영역에서 실행될 수 있음 --> 스레드와 관련 --> 서블릿 객체는 하나여도 그 객체가 지닌 메서드를 여러 번 호출할 수 있고, 하나의 서블릿 객체에서 메서드를 여러 번 호출시 여러 개의 스레드가 사용될 수 있고, 해당 스레드의 수 설정은 톰캣 기본 설정에서 설정할 수 있다.
4. 프론트컨트롤러 패턴
web.xml에 요청을 처리할 모든 Servlet/JSP 파일을 정의하고 매핑하기 힘들기 때문에
최초 앞단에서 요청을(request) 받아 요청을 처리할 클래스에 넘겨준다.
이 때 새로운 요청이 생기기 때문에 request와 response가 새롭게 new 될 수 있다.
그래서 RequestDispatcher가 필요하다.
5. RequestDispatcher
특정 주소의 요청이 들어오면 프론트 컨트롤러가 해당 요청에 맞는 자원을 찾아갈 수 있게 처리한다.
이 때 프론트 컨트롤러가 요청을 처리할 클래스를 매칭하는데,
프론트 컨트롤러의 요청을 처리할 클래스에 도달했을 때,
클라이언트로부터의 요청과 요청을 처리하고 나서의 응답 정보를 유지하면서
프론트 컨트롤러의 요청을 처리하고 응답할 정보를 담을 객체가 필요한데, 그게 RequestDispatcher다.
RequestDispatcher 객체를 사용한다면,
기존의 데이터를 들고 페이지간 이동을 가능하게 해준다.
즉 이동한 페이지에서 기존의 데이터 사용이 가능하다는 것
그런데 스프링에서는 FrontController 패턴과 RequestDispatcher를 합친 역할을 하는
DispatcherServlet이 있다.
6. DispatcherServlet
DispatcherServlet은 FrontController 패턴과 RequestDispatcher를 합친 기능을 갖는다.
7. 스프링 컨테이너
DispatcherServlet은 컴포넌트 스캔을 해서 src폴더 안의 자바 파일(*.java)을 메모리에 로딩한다.
예를 들어 @Controller @RestController @Service 등의 아노테이션이 클래스 위에 적혀있다면 해당 클래스를 메모리에 로드한다.
객체들을 메모리에 로딩한 후, 요청이 들어오면 요청에 따라(식별자 정보에 따라) 해당 요청을 처리할 객체를 매핑한다(주소분배)
DispatcherServlet이 컴포넌트 스캔하면 수 많은 자바 파일들이 객체로 생성되어 ApplicationContext에 등록된다.
request --- web.xml --- ContextLoaderListener --- DispatcherServlet
└ root-ApplicationContext 파일에 기반하여 ContextLoaderListener 가
스레드마다 따로 관리되어야 하는 것이 아닌 공통적으로 사용될 정보들을 객체로? 메모리에 로드한다.
예를 들면 DB 객체
ApplicationContext는 스프링 컨테이너를 의미하는 것 같고,
DispatcherServlet이 컴포넌트 스캔한 후에 수 많은 객체들이 생성되는데,
생성된 객체들은 ApplicationContext에 존재하고, 관리된다.
개발자가 new와 생성자를 통해 객체를 생성하는 것이 아니라
스프링에 의해 생성되는 것이므로 이를 제어의 역전(IoC)이라하며,
개발자들은 객체가 필요할 경우에 DI를 통해 주입받을 수 있기 때문에 편리하다.
ApplicationContext는 root-applicationContext와 servlet-applicationContext로 나뉜다.
servlet-applicationContext는 ViewResolver, Interceptor 등 객체를 생성하고,
웹과 관련된 어노테이션 Controller, RestController 등을 스캔한다.
------------ DispatcherServlet에 의해 servlet-applicationContext 파일이 실행된다.
root-applicationContext는 DB 관련 객체를 생성한다.
------------ ContextLoaderListener에 의해 root-applicationContext 파일이 실행된다.
web.xml에 의해 ContextLoaderListener가 실행되고, root-applicationContext는 servlet-applicationContext 파일보다
먼저 로드되기 때문에 servlet-applicationContext에서는 root-applicationContext가 로드한 객체를 참조할 수 있지만
그 반대는 불가능하다.
8. 요청 주소에 따른 적절한 컨트롤러로 요청(Handler Mapping)
9. 응답
클라이언트의 요청에 대해 html 파일로 응답할 경우 ViewResolver가 작동한다.
Data로 응답하게 되면 MessageConverter가 작동하게 되는데 메시지를 컨버팅할 때 기본 값이 JSON이다 --- @ResponseBody
참고
소켓관련 유튜브 영상
1. [코딩애플] 오늘의 테크 용어: 웹소켓이 뭐냐면 https://www.youtube.com/watch?v=yXPCg5eupGM
[메타코딩] 스프링부트 개념정리(이론)
8강 - HTTP가 무엇일까요? 정확히 알아야 해요
9강 - 톰켓이란 무엇인가요?
10강 - 서블릿 객체의 생명주기가 궁금해요!
11강 - 웹 배포서술자(web.xml)에 대해서 알려줘요!
12강 - 디스패처 서블릿이 무엇인가요?
13강 - 애플리케이션 컨텍스트란 무엇인가요?
14강 - 스프링부트가 응답(Response)하는 방법이 궁금해요!
'스프링' 카테고리의 다른 글
[스프링 입문] 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술 (0) | 2025.01.07 |
---|---|
[스프링] 스프링부트 개념정리(이론)_1~7강 정리 (2) | 2024.12.20 |