스프링부트 동작원리

김정현·2022년 9월 29일
0

스프링부트 동작원리

1.내장 톰켓을 가진다

  • 톰켓을 따로 설치할 필요 없이 바로 실행가능하다.

소켓통신

A와 B가 서로 통신하기 위해서는 운영체제가 제공하는 소켓이 필요

B가 A의 IP주소 : 5000포트로 연결되있기 때문에 C가 5000포트로 연결할수있는 방법이없다. 5000번포트로 다른 연결을 받기위해,

최초에 5000번포트는 연결의 용도로만 쓰고 5000번포트에 연결이되는 순간 B와 5000번 포트와 연결이 끊기고 새로운 포트와 연결, 새로운 스레드가 만들어진다.

C가 5000번포트가 연결이되고 새로운 포트와 연결이되고 스레드도 생성된다.

소켓통신은 계속연결되있기 때문에 부하가 크다

HTTP통신

http통신은 Stateless 방식으로 요청과 응답이 이루어지면 바로 연결이 끊김 부하가적음(문서전달의 목적),

다시 연결할때 새로운 것으로 인식 이런 단점을 보완한게 webServer

웹서버와 톰캣의 차이

웹서버는 갑, 클라이언트는 을이라고 했을때,

클라이언트측에서 자원을 요청하면 웹서버가 요청에대한 적절한 응답을 하는 구조이다

이때 자원은 static(정적) 자원만 주고 받을수 있다.

웹 서버에 jsp파일이나 자바코드로된 것을 요청이 왔을시, 웹 서버인 아파치는 정적 파일에만 응답이 가능하다.

아파치는 JSP파일 자바코드를 이해하지 못해 톰캣을 이용

톰캣은 JSP파일,자바코드가 요청이 되면 HTML파일로 번역해서 아파치에 넘겨주고, 아파치는 넘겨받은 HTML파일을 클라이언트에게 응답한다.

웹브라우저는 html,javascript,css 만 이해할수있다.

2.서블릿 컨테이너

  • 스프링에서는 URL : 자원접근을 통한 접근을 막고 URI : 식별자 접근을 통한 접근만 허용한다.

  • URL : HTTP://NAVAER.COM/A.png

  • URI : HTTP://NAVAER.COM/picture/a

  • 즉, 요청시에는 톰캣이 제어권을 가진다.

3.web. xml

  • ServletContext의 초기 파라미터

  • Session의 유효시간 설정

  • Servlet/JSP에 대한 정의

  • Servlet/JSP 매핑 : web.xml에는 자원들의 위치정보를 가지고있다. 식별자를 통해 요청한 자원의 위치가 어디 있는지 알려주고 이동할수 있도록 매핑

  • Mime Type 매핑

  • Welcome File list

  • Error Pages 처리 : 저장된 자원의 위치를 요청하는 것이 아닌 모르는 자원을 요청시, 이를 에러페이지처리

  • 리스너/필터 설정

  • 보안

4.FrontController

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

최초 앞단에서 request 요청을 받을때, 특정 주소(위의 이미지에서 .do)가 들어오면 FrontController라는 클래스로 보내라고 web.xml파일에 설정한다.

URI 혹은 자바 파일을 요청할때 바로 자원에 접근하지 못하고 톰캣으로간다.

톰캣으로 가면 request와 response객체를 자동으로 만들어내고 이때 요청을(Buffered 가변길이 문자열 형태의 데이터를 객체로 만듬)

request에는 요청한 사람에 대한 정보가 들어있다.(어떤 데이터를 요청하는지, 어떤 데이터를 가지고 왔는지 등)

이러한 정보를 토대로 응답해줄 response 객체를 만든다.

이때 web.xml에 sevlet/jsp 매핑이 너무 많으면 복잡해지기 때문에 , 특정 주소는 FrontController로 보내질수 있게 세팅을한다.

FrontController에서 한번 더 해당 자원에 접근할 수있게 request가 발생하고 이에 응답하기위해 response가 발생한다

이때 새로운 request와 response가 발생하기 때문에 기존의 request, response객체가 새롭게 갱신된다 따라서 이러한 재요청이 발생했을 때

기존의 request,response객체 정보가 없어지지 않고 유지시키는 방법이 필요한데, 이를위해 requestDispatcher를 사용한다.

5.RequestDispatcher

A에서 a.jsp라는 파일을 요청하면 이를 a.html로 변환하여 웹 브라우저에 보여준다.

이때 a.jsp에 대한 request,response객체가 만들어진다.

만약 이 화면에서 버튼을 클릭했을때 다음 페이지로 가는 새로운 요청을 한다면 이에 대한 새로운 응답을 해준다.

이때 b.html을 웹 브라우저에 보여주면서 b.jsp에 대한 새로운 request, response 객체가 만들어지기 때문에 기존의 객체는 사라지게 된다.

이를 해결하기 위해서 새로운 요청시, requestDispatcher를 이용하면 a.jsp에 있던 객체의 내용을 그대로 사용하면서 새로운 객체의 내용을 덮어쓸 수 있다.

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) 이다.

servlet-applicationContext

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

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

root-applicationContext

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

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

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

Bean Factory

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

8. 요청 주소에 따른 적절한 컨트롤로 요청 (Handler Mapping)

9. 응답

  • 응답하는 방법으로는 1. 파일 리턴 2. 데이터 리턴이 있다.
  • 파일을 응답할 경우 ViewResolver가 작동하고
  • 데이터를 응답할 경우 MessageConverter(@ResponseBody)가 작동한다.
  • MessageConverter는 오브젝트를 리턴할 때 json(Jackson) 타입으로 리턴한다.

  • ContextLoaderListener가 create되면서 applicationContext.xml이 읽어진다. 여기에서는 보통 DB에 관련된 객체들을 컴포넌트 스캔을 통해 메모리에 올린다.

  • 사용자의 요청이 들어오면 DispatcherServlet이 동작하여 컴포넌트 스캔을 통해서 자원들을 스캔하여 필요한 것들을 메모리에 올린다(IoC). 필요한 것들인지의 여부는 어노테이션으로 확인한다.

  • 모든 요청이 끝나면 Data 혹인 html파일을 응답한다.

0개의 댓글