Springboot 개념정리 - 동작원리

Yuri Lee·2020년 9월 17일
1

Springboot 개념정리

목록 보기
3/10

(1) 내장 톰켓을 가진다.
톰켓을 따로 설치할 필요 없이 바로 실행가능하다.

Socket: 운영체제가 가지고 있는 것,
A라는 대상과 B라는 대상이 있다. 서로 메시지를 교환하고 싶은 상황이다.

A가 소켓을 오픈한다. 포트번호가 필요하다. 5000번 포트를 열었다.

B -------------------> A
Ip주소:5000번

연결되면 A,B는 메시지를 주고 받을 수 있다. 근데 C가 A와 연결하고 싶을 때 이미 5000번 포트에 B가 연결되어 있으므로 연결할 방법이 없다. 그래서 어떻게 만들냐면..최초의 5000번 포트는 연결의 용도로만 쓰고, 연결되는 순간 새로운 소켓을 만든다. 그리고 이 포트는 보통 랜덤으로 만들어진다. b는 5001소켓으로 메시지를 보낸다.

[A]
5000 소켓 오픈! : main 스레드
5001 : 스레드 1

c가 5000에 접근하여 "나 연결할래..!!" 하면 새로운 소켓이 만들어진다. 랜덤임...(내가 직접 정할 수도 있음) 5002라고 하자

[A]
5000 소켓 오픈! : main 스레드
5001 : 스레드 1 : 연결이 끊김. 새로운 사용자의 연결을 받아야 하기 때문에
5002 : 스레드 2

소켓 통신: time slice에서 동시에 동작하는 것처럼 보일 수 있다. 소켓통신의 장점은 연결이 계속 되어있다. 끊어지지 않기 때문에 생각보다 부하가 굉장히 크다. 느려질 수가 있다. 연결이 100명 1000명으로 늘어나게 되면 늘어날 수 있다. http 통신은 연결을 지속시키지 않고 끊어버리는 stateless 방식을 사용한다. A, B가 있을 때 C라는 얘와 연결해서

http 통신은 단순하게 문서를 전달하는 통신이다. 부하가 적지만..다시 연결할 때는 항상 새로운 사람으로 인식한다.

스위스 cern 연구소: 입자물리연구소
굉장히 다양한 사람들이 모여 연구를 한다. 수만명이 있다.
A라는 사람이 새로운 연구를 시작해서 논문을 만들려고 한다.

  1. 전세계에 있는 자신의 주제와 동일한 내용의 논문을 다 읽어봐야 한다. 지금은 매우 편하지만 이 시대에는 인터넷이 딱히...종이로 볼 수도 있고..힘듦.. 방 2개에 컴퓨터에 논문들이 있지만 다 있는 것도 아니고..그래서 팀버너리스의 아이디어. 모든 컴퓨터를 하나의 서버로 연결하고, 자기가 쓴 논문을 업로드 한다. 통신에서 연결된 선응로 서치해서 논문을 검색할 수 있다. 필요한 논문이 있으면 쏙 들고올 수 있다. 소켓통신을 기반으로 하는 http통신!

http는 html이라는 확장자로 만들어진 문서를 필요한 사람에게 전달해주는 것이다.
팀버너리스 http의 창시자, 개인이 데이터 통제하는 새로운 웹 만들 것, 솔리드 프로젝트???
모든 데이터가 한군데에 다 몰려있다. 그럼 구글, 페이스북이 다 개인정보를 관리하고 있다. 데이터를 중앙집중화하지 않고, 분산화 하는 것이다. 블록체인처럼.....

톰켓?

http는 운영체제가 가지고 있는 소켓을 통해 만들어졌다. 시스템 콜. http기반은 소켓이다.

톰켓 vs 웹서버 차이

웹서버가 무엇일까? 내가 컴퓨터를 하나 구입했다. 내가 굉장히 재미있는 동영상들을 가지고 있다. 컴퓨터가 세개가 있다. 친구들은 내 동영상을 보고 싶다. 친구들이 내 데이터가 필요한 상황이다. 이럴 때 친구들은 ? word wide web으로 연결되어있기 때문에 .. 그 영상을 전송해줄 수 있겠니?...

내가 갑, 친구들은 을이다.
웹서버는 갑이다

http 통신은 항상 을이 갑에게 request 한다. request 요청한다. request 할 때는 내 컴퓨터가 어디있는지 위치를 알아야 해서 ip주소를 알아야 한다. 1,2,3 번 동영상 중에 어떤 동영상이 필요한지 정확히 알아야 하기 때문에 url이 필요하다.

소켓통신은 연결이 지속되어있는 통신이다.

웹서버는 흔히 아파치를 사용한다.
컴퓨터: C:\work

아파치는 .JSP(자바코드)요청 시에 응답하지 못한다. 톰켓을 단다. 그럼 자기가 이해하지 못하는 파일이 오면 그 제어권을 톰켓에게 넘긴다. 톰켓은 .JSP파일 안에 있는 모든 자바코드를 컴파일하고, 컴파일이 끝나면 컴파일 된 데이터를 .html에 덮어쓴다. 톰켓은 자바파일을 컴파일하고 html로 만들어 아파치에게 돌려준다. 아파치는 .html파일을 응답해준다~

아파치는 요청한 파일을 응답해준다. 톰켓은 자바코드가 요청되면 html파일로 번역해서 돌려준다.

(2) 서블릿 컨테이너

출처 : https://minwan1.github.io/2018/11/21/2018-11-21-jsp-springboot-%EB%8F%99%EC%9E%91%EA%B3%BC%EC%A0%95/

----요청----> .html, .css, .png 정적인 파일을 요청하면 아파치가 돈다. 톰켓은 일을 하지 않는다. 아파치가 일을 한다.

스프링에서도 그럼 .html을 요청하면 톰켓이 일을 하지 않는다? 맞다. 근데 스프링에서는 이런 파일을 요청할 수 없다. 왜냐하면

URL: 자원접근
URI: 식별자 접근

특정한 파일 요청은 할 수 없다. 요청시에는 무조건 자바를 거친다. 무조건 아파치는 톰켓에 넘어가준다.

url: http://naver.com/a.png
uri: http://naver.com/picture/a

---요청----> .JSP

최종적으로 만들어지는 객체는 HttpServletRequest, HttpServletResponse 이다. 이건 스프링이 아니라 톰켓이 들고 있는 객체이다.

웹이라는 것은 request와 response의 여행이다.

(3) web.xml

A 나라 (성) 과 문지기로 비유하기

-ServletContext의 초기 파라미터
ex) 암구호: 왈
-Session의 유효시간 설정
ex) 3일
-Servlet/JSP에 대한 정의

-Servlet/JSP 매핑

-Mime Type 매핑
니가 들고올 데이터가 어떤 타입이야? 어떤 물건이야? 아무것도 안들고 온 애들은 그냥 성구경하기.. get방식:select라고 한다. 쌀이라는 데이터를 들고 왔으면 쌀창고로 데이터를 보냄. 우리 나라(성)에서 먹을 수 있을지 판단...가공하는 일!

-Welcome File list

그냥 왔는데요? 하면..아무 이유 없이 들어온 얘들은 일단 광장으로 보내~ 일거리가 많기 때문에, 이건 관리자가 누구냐에 따라 달라질 것이다.

-Error Pages 처리

파??가 들어옴. 문지기 멘붕. 관리자는 이상한 게 들어오면 에러로 던져~이상한 광장으로 던져~

-리스너/필터 설정

필터라는 것은 a가 들어왔을 때 a의 신분을 확인하는 것이다. b나라가 들어오면 안되니까. 만약 a 나라가 총소지가 불가라면 a의 총을 빼앗아야 함. 그래야 성에 입장 가능!
리스너는 술 잘먹는 사람만 확인하는 대리인?
문지기가 일을 하고 있는 동시에 대리인이 지켜본다. 옆에서. a,b,c,d
대리인: "너 술 잘먹니?"
a: "네"
b: "네"
c: "아니오"
c 한테 실제로 술 먹여봄. 양반이 얘 데려오래. 데려간다~이게 리스너임
-보안

웹서버에 진입을 해 최초에 도는 게 web.xml이다. web.xml은 초반에 돈다.
Servlet/JSP 매핑시에 문지기가 해야할 일이 매우 많다. 문지기가 해야할 일을 줄이기 위해 FrontController 패턴을 이용할 것이다.

여기에서 Servlet/JSP 매핑시(web.xml에 직접 매핑 or @WebServlet 어노테이션 사용)에 모든 클래스에 매핑을 적용시키기에는 코드가 너무 복잡해지기 때문에 FrontController 패턴을 이용함.

참고 : https://galid1.tistory.com/487

(4) FrontController 패턴
최초 앞단에서 request 요청을 받아서 필요한 클래스에 넘겨준다. 왜? web.xml에 다 정의하기가 너무 힘듬.

문지기가 web.xml에 모든 정의를 하면 너무 복잡해지기 때문에...

이때 새로운 요청이 생기기 때문에 request와 response가 새롭게 new될 수 있다. 그래서 아래의 RequestDispatcher가 필요하다.

(5) RequestDispatcher
필요한 클래스 요청이 도달했을 때 FrontController에 도착한 request와 response를 그대로 유지시켜준다. 이게 있어야 페이지 간 데이터 이동이 가능하다.

(6) DispatcherServlet
FrontController 패턴을 직접짜거나 RequestDispatcher를 직접구현할 필요가 없다. 왜냐하면 스프링에는 DispatcherServlet이 있기 때문이다. DispatcherServlet은 FrontController 패턴 + RequestDispatcher이다.

DispatcherServlet이 자동생성되어 질 때 수 많은 객체가 생성(IoC)된다. 보통 필터들이다. 해당 필터들은 내가 직접 등록할 수 도 있고 기본적으로 필요한 필터들은 자동 등록 되어진다.

(7) 스프링 컨테이너
DispatcherServlet에 의해 생성되어지는 수 많은 객체들은 ApplicationContext에서 관리된다. 이것을 IoC라고 한다.

ApplicationContext

IoC란 제어의 역전을 의미한다. 개발자가 직접 new를 통해 객체를 생성하게 된다면 해당 객체를 가르키는 레퍼런스 변수를 관리하기 어렵다. 그래서 스프링이 직접 해당 객체를 관리한다. 이때 우리는 주소를 몰라도 된다. 왜냐하면 필요할 때 DI하면 되기 때문이다.

DI를 의존성 주입이라고 한다. 필요한 곳에서 ApplicationContext에 접근하여 필요한 객체를 가져올 수 있다. ApplicationContext는 싱글톤으로 관리되기 때문에 어디에서 접근하든 동일한 객체라는 것을 보장해준다.

ApplicationContext의 종류에는 두가지가 있는데 (root-applicationContext와 servlet-applicationContext) 이다.

a. servlet-applicationContext

servlet-applicationContext는 ViewResolver, Interceptor, MultipartResolver 객체를 생성하고 웹과 관련된 어노테이션 Controller, RestController를 스캔 한다.

============> 해당 파일은 DispatcherServlet에 의해 실행된다.

b. root-applicationContext

root-applicationContext는 해당 어노테이션을 제외한 어노테이션 Service, Repository등을 스캔하고 DB관련 객체를 생성한다. (스캔이란 : 메모리에 로딩한다는 뜻)

============> 해당 파일은 ContextLoaderListener에 의해 실행된다. ContextLoaderListener를 실행해주는 녀석은 web.xml이기 때문에 root-applicationContext는 servlet-applicationContext보다 먼저 로드 된다.

당연히 servlet-applicationContext에서는 root-applicationContext가 로드한 객체를 참조할 수 있지만 그 반대는 불가능하다. 생성 시점이 다르기 때문이다.

출처 : https://minwan1.github.io/2018/11/21/2018-11-21-jsp-springboot-%EB%8F%99%EC%9E%91%EA%B3%BC%EC%A0%95/

Bean Factory

필요한 객체를 Bean Factory에 등록할 수 도 있다. 여기에 등록하면 초기에 메모리에 로드되지 않고 필요할 때 getBean()이라는 메소드를 통하여 호출하여 메모리에 로드할 수 있다. 이것 또한 IoC이다. 그리고 필요할 때 DI하여 사용할 수 있다. ApplicationContext와 다른 점은 Bean Factory에 로드되는 객체들은 미리 로드되지 않고 필요할 때 호출하여 로드하기 때문에 lazy-loading이 된다는 점이다.

(8) 요청 주소에 따른 적절한 컨트롤로 요청 (Handler Mapping)
GET요청 => http://localhost:8080/post/1

해당 주소 요청이 오면 적절한 컨트롤러의 함수를 찾아서 실행한다.

참고: https://minwan1.github.io/2017/10/08/2017-10-08-Spring-Container,Servlet-Container/

DispatcherServlet

A

String Hello() {
return "Hello"
}

(9) 응답
html파일을 응답할지 Data를 응답할지 결정해야 하는데 html 파일을 응답하게 되면 ViewResolver가 관여하게 된다.

하지만 Data를 응답하게 되면 MessageConverter가 작동하게 되는데 메시지를 컨버팅할 때 기본전략은 json이다.


https://asfirstalways.tistory.com/334

기억해야 할일: 흐름을 기억해라. 최초 입구에서 web.xml이 자기가 해야할일을 기억하고 해야할일이 많으니까 DispatcherServlet에게 넘겨서 일감도 주고, 미리 띄어놔야 하는 것은 ContextLoaderListener를 이용해서 데이터베이스 관련된 것들을 미리 띄어놓고..

profile
Step by step goes a long way ✨

0개의 댓글