티스토리 뷰

반응형

메타코딩 - 스프링부트 개념 정리 with JPA를 기반으로 작성된 글입니다.

 

1. 스프링부트 동작 원리

(1) 내장 톰켓을 가진다.

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

 

 Socket : 운영체제가 가직고 있는 것!

-- 소켓통신

A가 5000번 포트에 소켓을 오픈한다.

B가 ip주소와 포트번호 5000으로 A와 통신

이때, ip5000번은 B가 쓰고 있으므로 C는 A와 통신이 불가능하다.

 

그래서 A의 5000번 포트는 연결의 용도로만 사용 후 연결이 되는 순간 새로운 소캣(5001)을 생성하고 연결을 끊는다.

B는 5000번 포트와 연결이 끊기고 5001번을 통해 A와 통신을 진행한다.

하지만 CPU는 5001번에서 자원을 모두 사용 중이라 C의 통신을 받을 수가 없다.

 

따라서 새로운 포트를 생성할 때는 새로운 스레드를 만든다.

main 스레드는 계속 새로운 사용자의 요청을 받고, 새롭게 생성된 소켓과 스레드로 통신을 주고받는다.

*time slice  : 시간을 쪼개서 활동하지만 동시 동작하는 것처럼 보임

 

장점 : 연결이 되고 나면 서버에서 통신을 하는 주체를 확인할 수 있다.

단점 : 연결이 계속 이어지기 때문에 부하가 심하게 올 수 있다.

 

-- http 통신(socket) - Stateless 방식 (문서를 전달하는 통신)

요청을 받으면 응답을 해주고 연결을 끊어버린다.

 

장점 : 부하가 적다.

단점 : 요청자가 누구인지 모른다.  -> 이러한 단점을 보안한 것이 웹서버

 

-- 톰켓

 일반적으로 웹서버는 요청(request)이 들어오면 응답(response)을 해준다. (요청이 없다면 응답도 불가)

웹 서버는 주로 아파치를 사용한다. 하지만 JSP 또는 자바코드의 요청이 오면 아파치는 자바코드를 이해하지 못한다.

톰켓은 JSP파일 등의 모든 Java파일을 컴파일한 후 ->. html로 변환시켜 준다. 그리고 다시 아파치에게 넘긴다.

 

 

(2) 서블릿 컨테이너

출처 : https://parkyounghwan.github.io/2019/08/23/spring/java-servlet-container/

URL (Uniform Resource Locator) : 자원 접근 ex) http://naver.com/a.png

URI (Uniform Resource Identifier) : 식별자 접근 ex)http://naver.com/picture/a

  •  스프링은 URL 접근이 불가능하고 요청 시에 무조건 자바를 거친다. 따라서 반드시 톰켓을 거치게 된다.
  •  최초 요청 시 새로운 스레드 생성과 함께 서블릿 객체를 생성한다. 그리고 각각의 요청마다 스레드와 서블릿을 생성한다.
  •  이후 최대치의 스레드가 생성된다면, 다음 요청은 대기한다.
  •  위의 요청은 대기가 끝난 후 새로운 객체 생성이 아니라 기존의 생성된 객체를 재사용한다(ThreadPool).

 

 

(3) web.xml

-ServletContext의 초기 파라미터 (암구호)
-Session의 유효시간 설정 (인증 유효시간)
-Servlet/JSP에 대한 정의
-Servlet/JSP 매핑 (요청한 데이터의 위치를 알려줌)
-Mime Type 매핑 (가져온 데이터의 타입 확인, 가공) - 추가 학습 하기
-Welcome File list (위치도 데이터도 없이 온 요청을 모아둠)
-Error Pages 처리 (잘못된 요청 수신 시 에러 페이지)
-리스너/필터 설정 (특정 조건 확인)
-보안

 

웹서버에 진입을 하면 최초에 도는 것이 web.xml이다.

 

 

(4) FrontController 패턴

 최초 앞단에서 request 요청을 받아서 필요한 클래스에 넘겨준다. 왜? web.xml에 다 정의하기가 너무 힘들기 때문.

 

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

 

 

(5) RequestDipatcher

 필요한 클래스 요청이 도달했을 때 FrontController에 도착한 request와 response를 그대로 유지시켜준다.

 

 

(6) DispatchServlet

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

 

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

 

 

(7) 스프링 컨테이너

 DispachServlet에 의해 생성되는 수많은 객체들은 어디에서 관리될까?

 

 - 첫째, ApplicationContext

 (DispachServlet이 component scan 할 때) 수많은 객체들이 ApplicationContext에 등록된다. 이것을 IoC라고 한다. IoC란 제어의 역전을 의미한다. 개발자가 직접 new를 통해 객체를 생성하게 된다면 해당 객체를 가리키는 레퍼런스 변수를 관리하기 어렵다. 그래서 스프링이 직접 해당 객체를 관리한다. 이때 우리는 주소를 몰라도 된다. 왜냐하면 필요할 때 DI 하면 되기 때문이다. DI를 의존성 주입이라고 한다. 필요한 곳에서 ApplicationContext에 접근하여 필요한 객체를 가져올 수 있다. 

ApplicationContext는 싱글톤으로 관리되기 때문에 어디에서 접근하든 동일한 객체라는 것을 보장해준다.

 

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

 

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

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

 

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

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

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

출처 : https://jaehun2841.github.io/2018/10/21/2018-10-21-spring-context/#group

 - 둘째, Bean Factory

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

 

 

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

 GET요청 => http://localhost:8080/post/1

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

 

 

 (9) 응답

 html 파일을 응답할지 Data를 응답할지 결정해야 하는데,

- html 파일을 응답하게 되면 ViewResolver가 관여하게 된다.

ex) hello라는 파일을 보낼 때 web-INF/views/hello.jsp, 경로와 확장자까지 자동으로 붙여서 보내준다.

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

ex) 일반적인 문자열이라면 "hello"를 리턴 하지만, 객체라면 json 형식으로 변환후 리턴한다 {"id":1, "name":"홍길동"}

 

톰켓 실행시 - web.xml 로딩 → ContextLoaderListener 생성 → root-context.xml(applicationContext.xml) 로딩 → ServiceImpl, DAO, VO 메모리에 띄어짐 → request 요청 → DispatcherServlet 동작 → servlet-context.xml에 의해 DispatcherServlet 읽힘 → DispatcherServlet이 주소분배 → 배정된 Controller에서 응답(Response)함

출처 : https://javannspring.tistory.com/231

 

참고 영상 : https://www.youtube.com/watch?v=pifmwZWWbuY&list=PL93mKxaRDidG_OIfRQ4nztPQ13y74lCYg&index=8&ab_channel=%EB%A9%94%ED%83%80%EC%BD%94%EB%94%A9

반응형
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
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 31
글 보관함