3. 스프링부트 동작원리

hyuun01·2023년 1월 30일
0

스프링부트

목록 보기
3/3
post-custom-banner

1) 내장 톰캣을 가짐

소켓 통신

  • 소켓은 운영체제가 가지고 있음
  • timeslice
  • 부하 크다(스레드 늘어날수록)
    -> http 통신은 stateless 방식
  • A, B 사이의 메시지 교환 위해서는
    A가 소켓 오픈(포트번호), A의 ip주소와 포트번호로 연결
    -> C와 연결하기 위해서는 새로운 소켓 불가, 새로운 스레드 생성으로 연결!

http

  • 소켓으로 만들어짐

톰켓 v.s. 웹서버

  • request : 요청하는 쪽은 요청받는 쪽의 ip 주소, url(자원요청주소) 알아야

  • response: 응답하는 쪽은 응답받는 쪽의 주소 모름
    -> 갑이 다른 을에게 무언가 보내고 싶다면 지속적으로 유지되는 소켓 필요

  • 웹서버 ex) 아파치
    - static 자원을 응답
    - .jsp(자바코드) 이해X

  • 아파치 + 톰켓
    &39;아파치가 이해할 수 없는 파일은 톰켓에 넘김
    -> 톰켓은 .jsp 속 모든 자바코드를 컴파일
    -> 컴파일된 결과를 .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/

url, uri

요청이 왔을 때 서플릿 컨테이너가 객체를 생성하는 방식

  • request(java 자원 요청) 시 처음이라면 : new 객체, 스레드1
    1) 서블릿 객체 생성
    2) 서블릿 객체의 init() 메소드 호출
    3) 서블릿 객체의 service() 메소드 호출 : 스레드1
    : POST, GET, put, delete 중 무엇인지 체크 -> 그 메소드 호출
    ex) get이라면 get() 메소드 호출 : DB연결, 데이터, html 담아서 응답

  • request 시 처음이 아니라면 : 객체 재사용, 새로운 스레드
    1) service() 메소드 호출 : 새로운 스레드
    : POST, GET, put, delete 중 무엇인지 체크 -> 그 메소드 호출 :

c.f. 같은 객체인데 왜 스레드가 여러 개일 수 있을까?
자바에서 클래스 메소드는 heap에 저장
-> 메소드 호출 시 메소드 호출에 이용되는 정보는 스택에 저장
-> 호출될 때마다 스택에 따로 저장됨
-> 같은 객체여도 스레드가 여러개인 것!!

  • 톰켓 기본 설정
    - 스레드 Auto 설정 시 20개 : 최대 스레드는 20개(21번째는 대기)
    : 재사용 pooling 기법

  • 최대 스레드 수가 너무 적은 경우
    : scale-up(컴퓨터 업그레이드), scale-out(컴퓨터 수 늘림)

3) web.xml

  • ServletContext의 초기 파라미터 설정
    -> 보안(정상적으로 들어온 자들만 초기 파라미터 값 알아)
  • session의 유효시간 설정
    : 유효시간 연장도 web.xml이 수행
  • Servlet/JSP에 대한 정의
  • Servlet/JSP 매핑
    : 어디로 가는지
  • Mime Type 매핑
    : 어떤 물건을 들고 왔는지 그 타입
    : 아무것도 안 가지고 왔다면 get 방식 사용 : select(가져 가려고)
  • Welcome File list
  • Error Pages 처리
  • 리스너/필터 설정
    - 리스너 : 특정 이벤트의 발생을 기다리다 실행되는 메소드 or 함수 or 그 메소드를 가지는 객체
  • 보안

4) FrontController 패턴

  • 최초 앞단에서 request 요청을 받아서 필요한 클래스에 넘겨줌
    b/c web.xml에 다 정의하기가 너무 힘듦
  • 이때, 새로운 요청 생김 -> request, response가 새롭게 new 될 수 있음
    -> RequestDispatcher 필요

  • 요청이 url or 자바 파일 -> 톰켓(web.xml -> frontController)

  • 특정 주소의 request를 FrontController가 낚아 챔 -> request

  • A의 request, response 정보를 톰켓이 메모리에 저장

  • frontController에서 주소 낚아채서 다시 request 시,
    기존 A의 request, response 정보를 frontController의 request, response 정보로 덮어 써야

  • 기존 A의 request, response 정보를 따로 유지하고 싶으면? : RequestDispatcher 사용

5) RequestDispatcher

  • 필요한 클래스 요청이 도달했을 때 FrontController에 도착한 request와 response를 그대로 유지시킴
    -> 기존 페이지의 데이터 들고 페이지 이동 가능

6) DispatchServlet

: frontcontroller 패턴 + requestdispatcher

  • 스프링에서 제공 -> frontcontroller 패턴을 직접짜거나 requestDispatcher 직접 구현할 필요X
  • DispatchServlet이 자동생성되어질 때 수많은 객체가 생성(IoC)됨 (보통 필터들)
    -> 해당 필터들은 직접 등록O, 기본적으로 필요한 필터들은 자동등록됨
  • 컴포넌트 스캔 수행
    - 컴포넌트 스캔은 전체 스캔이 기본
    - annotation 이용해 스캔할 부분 특정 가능
  • 주소 분배

ContextLoaderListener

  • 공통적인 것(DB 관련된 것, ...)
  • root_applicationContext 파일 읽어 공통적으로 쓰이는 부분을 메모리에 로드

7) 스프링 컨테이너

dispatchServlet에 의해 생성되는 객체들은 어디에서 관리?

ApplicationContext

= root-applicationContext + servlet-applicationContext

  • 싱글톤으로 관리됨 -> 어디에서 접근하든 동일한 객체임을 보장함

    servlet-applicationContext

  • ViewResolver, Interceptor, MultipartResolver 객체를 생성

  • 웹과 관련된 어노테이션만 스캔

  • 해당 파일은 DispatcherServlet에 의해 실행됨

  • root-applicationContext에서 로드한 객체 참조 가능

    root-applicationContext

  • 그 외 어노테이션 스캔 ex) Service, Repository, ...

  • DB 관련 객체 생성

  • 해당 파일은 contextloaderlistener에 의해 실행됨

  • servlet-applicationContext보다 먼저 로드됨 (contextloaderlistener은 web.xml에 의해 실행되므로)

  • servlet-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에 등록 : @Bean, @Controller
  • bean factory에 등록된 객체는 필요할 때 getBean() 메소드 통해 호출해 메모리에 로드 가능(초기에 메모리 로드X) : IoC
  • 필요 시 DI 가능
  • lazy-loading : 미리 로드X, 필요할 때 호출해 로드 (ApplicationContext와의 차이)
@configuration
class A {
	
    @Bean
    객체 메소드(){
    	return 객체();
    }
}

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

  • 요청 주소에 따라 적절한 컨트롤러 함수 찾아서 실행

9) 응답

  • html 파일 응답할 지 data 응답할지 결정
  • html 파일을 응답하면 ViewResolver 가 관여
A{
	String Hello(){
    	return "hello";	// viewresolver -> web-inf/views/hello.jsp로 
    }
}
  • data를 응답하게 되면 MessageConverter가 작동
    - 메시지 컨버팅 시 기본전략은 json
    • jackson : json으로 컨버팅하는 messageConverter
A{
	@ResponseBody
	String Hello(){
    	return user;	// 메시지 컨버터가 json으로 바꾸어 response
        // {"id": 1, "name"; "홍길동"}
    }
}

user {
	int id = 1
    String name = "홍길동"
}


출처 : https://asfirstalways.tistory.com/334


출처 : 인프런 "스프링부트 개념정리(이론)" 8~14강
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-%EA%B0%9C%EB%85%90%EC%A0%95%EB%A6%AC#reviews
https://getinthere.tistory.com/11

post-custom-banner

0개의 댓글