Dev/Spring.SpringBoot

[SpringBoot] [Inflearn - 무료] 스프링부트 개념정리(이론)

pu3vig 2023. 2. 8. 09:27
728x90
  • target:  스프링부트 개념정리 1 ~ 14강(완)

 


  • method: 

1. 스프링이란?

더보기
  • Framework(어느정도 정해진 개발 틀 제공)
  • Free Open Source(커스터마이징 가능)
  • *Inversion of Control(IoC: 제어의 역전) 컨테이너 보유
  • *Dependency Injection(DI: 의존성 주입) 지원
  • *Filter를 보유
  • *Annotation을 보유
  • *MessageConverter를 보유(Default: Json)
  • *BufferedReader / BufferedWriter를 쉽게 사용 가능
  • 지속 발전 가능

 

IoC(Inversion of Control)

- Abstract Class(추상적인 개념) -> Class(논리적인 개념: 설계도면) -> Object(객체: 설계도면에 맞는 인스턴스를 생산할 수 있는 공장) -> Instance(인스턴스: 객체를 통한 생산된 실체화)

- Instance는 한 method에서 생성되어, 해당 method가 종료되기 전까지 heap 메모리에서 상주

- 해당 Instance는 다른 method에서 참조하기 위해서는 일반적으로 최초 생성된 method로 부터 참조주소를 전달하고, 받는 부분이 필요

- 위와 같은 사유로 로직의 복잡함을 편리하게 해주기 위해서 스프링에서는 이와 같이 여러 method들에서 사용될 객체를 미리 설정해주면, 이 객체들을 스캔하여 Instance화 하고 heap 메모리에서 보유하여 스프링이 관리하게 하는 기술

 

DI(Dependency Injection)

- 스프링에서 관리하는 heap 메모리에 올라온 Instance를 서로 다른 method에서 동일한 Instance(=Singleton) 를 참조할 수 있도록 하게 하는 기술

 

※ Filter

- Tomcat 같은 WAS Filter(web.xml)외에 스프링에서 제공하는 Filter(Interceptor)가 존재

 

※ Annotation

- Annotation은 Compile Checking 시, Compiler가 컴파일 할 때, Hint 및 Guide를 제공하는 주석

- @Bean, @Controller, @Service, @Component, @Autowired ... 등이 있으며, IoC를 통해 heap에 생성된 객체를 런타임 시, Reflection(분석)하여, heap 메모리의 인스턴스를 객체에 할당(=DI)

 

※ MessageConverter

- 타입은 같으나 형식이 다른 경우(ex. Java object와 python object) MessageConverter가 공통화된 표준 양식을 제공

- 스프링은 기본적으로 MessageConverter를 보유하고 있으며, 과거에는 xml을 통해 이루어졌으나, 최근에는 Json으로 대부분 대체되어 스프링부트는 기본적으로 Json 사용

 

※ BufferedReader / BufferedWriter (@RequestBody / @ResponseBody)

- ByteStream을 통해서 들어온 데이터를 InputStreamReader를 사용하게 되면, 1byte(=8bits)를 통해서 한개의 문자를 변환하지만, 배열로 수신할 경우, 배열의 길이만큼 문자 수신 가능 (단, 배열의 길이보다 많거나 적은 데이터는 데이터 손실이나 메모리 낭비가 발생)

- 가변 길이의 문자 송수신을 위해서 BufferedReader를 채택

- @RequestBody는 BufferedReader를 통해서 데이터 수신하고, @ResponseBody는 BufferedWriter를 통해서 데이터를 송신

 


2. JPA란?

더보기
  • *Java Persistence API
  • *ORM
  • 반복적인 CRUD 작업 생략
  • DB - OOP의 불일치성을 해결하기 위한 방법론 제공 (DB는 객체저장 불가능)
  • *Persistence Context(영속성 컨텍스트) 보유
  • *OOP의 관점에서 Modeling (상속, 콤포지션, 연관관계)
  • 방언 처리가 용이하여 Migration / 유지보수에 좋음 (추상화객체 JPA를 통한 DB 연동 시, DB 변경에 용이)
  • 쉽지만 어려움

 

※ Java Persistence API

- Persistence(영속성)란, RAM과 같은 휘발성 데이터가 아닌 ROM이나 HDD 같은 비휘발성을 의미

- Java Persistence API라 함은 Java 데이터를 비휘발성으로 저장하기 위한 API(Application Programming Interface)

 

※ ORM

- ORM(Object Relational Mapping)은 RDB(Relation Data Base)와 객체 모델과의 매핑을 통해서 객체를 통해 DB 데이터를 간접적으로 컨트롤하여 불일치를 해소하는 기술

- Persistent API (ex. JPA, Hibernate 등...)

- 예시와 같은 방식으로 DB - OOP의 불일치성을 해결가능

예시)

/**
Table) TB_CODE
|------------------------------------|
|  CODE    | CODE_NM  |  UPPER_CODE  |
|------------------------------------|
|   1      | 사과      |     1       |
|------------------------------------|
|   2      | 배        |     1       |
|------------------------------------|
|   3      | 돼지      |     2       |
|------------------------------------|

Table) TB_GRP_CODE
|-----------------------------|
|  CODE    | CODE_NM  |  DESC |
|-----------------------------|
|   1      | 과일     | 달다  |
|-----------------------------|
|   2      | 육류     | 맛있다|
|-----------------------------|

Query)
SELECT A.CODE
     , A.CODE_NM AS FOOD
     , B.CODE_NM AS TYPE
     , B.DESC
  FROM TB_CODE A
     , TB_GRP_CODE B
 WHERE A.UPPER_CODE = B.CODE
 
View)
|------------------------------------|
|  CODE    | FOOD  |  TYPE  |  DESC  |
|------------------------------------|
|   1      | 사과  |  과일  | 달다   |
|------------------------------------|
|   2      | 배    |  과일  | 달다   |
|------------------------------------|
|   3      | 돼지  |  육류  | 맛있다 |
|------------------------------------|
**/

// DB의 경우 위와 같이 2개의 테이블을 생성하고, 쿼리를 통해서 하나의 테이블과 같은 View를 생성
// 이를 Java에서 DB방식이 아닌 OOP관점에서 프로그래밍 시 View를 위한 하나의 별도 객체를 생성하지 않고,
// 아래와 같이 2개의 클래스로 프로그래밍

class TbCode {
    private int code;
    private String codeNm;
    private String upperCode;

    private TbGrpCode tbGrpCode;	// TbCode에 TbCode의 그룹코드 정보를 객체 자체를 변수로 선언하여 매핑
}

class TbGrpCode {
    private int code;
    private String codeNm;
    private String desc;
}

 

※ Persistence Context

- Java와 DB 사이의 ORM을 통한 데이터 CRUD에 대한 meta 정보를 보유

- 객체에서 데이터 요청 시, 보유하고 있지 않은 데이터에 대해서 DB로부터 조회 후, 보관 및 객체에 전달

- 객체의 데이터 변경 정보에 대해서 Context는 해당 객체의 변경 정보를 저장하고, DB에 변경 사항을 동기화

 

※ OOP의 관점에서 Modeling

- 객체 모델링에는 상속, 컴포지션을 통해 모델링 할 수 있음

- A, B, C 각각의 클래스에서 동일하게 사용할 특정 변수의 경우, D클래스를 생성하여 변수 생성 및 A, B, C에서 상속

- A 클래스에서 B 클래스의 데이터를 구성해야하는 경우, 컴포지션을 통해 구현

- 이와 같이 구현된 객체를 통해서 모델링을 통해 DB에 테이블 생성 가능

- 상속은 각각의 별개의 테이블이 아니라 추가 컬럼형태로 생성되고, 컴포지션의 경우, 개별 테이블로 생성

 


3. 스프링부트 동작원리

3.1) Tomat(내장 톰캣)

더보기

※ 번외

소켓통신(stateful)

최초 접근 시, Server에서 Open한 소켓을 통해서 연결을 수립하고, 다른 포트를 통해서 데이터 송수신을 수행
Server측에서는 Open한 소켓은 Main Thread로 연결 요청 및 수립을 진행
연결이 정상적인 경우, 새로운 Thread를 통해서 새로운 소켓을 생성하여 Server와 Client 연결하고 데이터 송수신
Client측에서는 연결 수립이 되면, Server에서 제공한 새로운 포트를 통해서 데이터 송수신

---

Client의 요청에 대한 Server의 응답이 해당 Client에게로 응답됨을 알 수 있음(stateful)


다수의 Client가 Server에 접근 시, 서버 부하가 심해짐
  

HTTP통신(stateless)

Server는 Client로부터 요청이 있는 경우에만, 응답을 하고, 소켓연결은 유지하지 않음
팀 버너스리(Tim Berners-Lee)에 의해 최초 개발되었으며, 여러 컴퓨터에서 각자의 PC에 있는 html을 하나의 Server에 모아서 다양한 장치에서 접근할 수 있도록 구현한 것이 HTTP통신의 시초

---

다수의 Client가 하나의 Server에 접근이 가능
Client측에서는 Server로부터 응답을 받지만, 해당 응답이 Client에게 정상적으로 도달했음을 보장할 수 없음(stateless)

 

※ Web / WAS

- Web 서버는 정적인(Static) 자원을 클라이언트의 요청에 대한 응답만 함

- 정적인 자원이란, 단순 텍스트 문서나, 이미지 등과 같이 특별한 프로그래밍이 필요없는 자원

- html, javascript, css, 각종 이미지, 동영상 파일 등

- Apache

 

- WAS 는 특정 프로그래밍된 파일에 대한 요청 시, 이 파일을 컴파일하여, html형태로 변환하여 응답

- jsp, asp 등 프로그래밍 언어를 통해 작성된 파일

- Tomcat


3.2) Servlet Container

[그림 1] Http Service

※ URL / URI

- URL : 자원 접근, 스프링에서는 URL 접근 허용 X, Apache에서 처리

- URI : 식별자 접근, Tomcat에서 처리

 

※ Servlet Container(서블릿 객체 생성주기)

최초의 클라이언트 요청 시, 서블릿 객체 생성 (init(), service(), get(), post() ... 등의 메소드 보유)

- init(): 최초 요청 이후에는 init() 메소드를 호출하지 않음

- service(): Post, Get, Put, Delete

- 서블릿 객체는 무조건 1개만 생성

- 클라이언트 요청은 thread가 처리

- thread는 thread pool에서 관리되며, 사용자 요청시 thread가 해당 요청을 처리(응답)

- thread는 사용자 요청을 처리하고 나면 시스템 설정에 따라 thread pool에서 대기하거나, 자원(메모리)을 반납하고 사라짐

- thread pool은 최소 대기 thread 수, 최대 thread 개수 등의 시스템 설정에 따라 thread를 관리

- 단일 Server 성능 업: Scale-up

- 다중 Server 병렬 분산 처리: Scale-out


3.3) web.xml

더보기
  • Servlet Context의 초기 파라미터 (인증값)
  • Session 유효시간 설정
  • Servlet / JSP 정의 및 매핑
  • Mime Type(Request시 포함한 데이터 타입) 매핑
  • Welcome File List (인덱스 페이지)
  • Error Pages 처리 (400, 404, 500 에러 등...)
  • Listener / Filter 설정
  • 보안

 


3.4) FrontController Pattern

- 특정주소를 통한 요청(URI 혹은 Java file)의 경우, web.xml에서 FrontController로 이관

   (web.xml에서 모든 URI에 대한 매핑을 진행 시, 너무 복잡해지기에 FrontController에서 처리)

- Request Dispatcher를 통해 request / response 생성

  (최초의 request / repsonse 정보를 유지하기 위하여 요청한 Class에 도달 시, 기존의 request / response 객체에 덮어씀)


3.5) Request Dispatcher

- FrontController로 들어온 최초의 request / response 에 대한 정보를 유지하면서, 자원에게 접근할 때의 request를 새로 생성하는 기법


3.6) Dispatcher Servlet

- FrontController Pattern + RequestDispatcher로 스프링에서 자동 생성

- IoC를 위해서 컴포넌트 스캔을 통해 다양한 Bean 객체 및 Filter를 생성하여 메모리에 올림

- 커스터마이징을 통해 초기에 생성할 Bean 객체 및 Filter 추가 가능

- @ (Annotation)을 통해서 Dispatcher Servlet에서 메모리에 사전 생성할 Class의 힌트를 제공

- Annotation은 개발자가 직접 추가 생성 가능


3.7) Spring Container

더보기

① web.xml로 부터 *Servlet Container을 loading

② Servlet Container에서 Context Loader Listener를 통해 공통 컴포넌트를 loading

③ Spring Container(ROOT)에서 ServiceImpl 및 DAO, VO 생성

④ Client로부터 요청이 있는 경우, 유휴 Thread 사용 or Thread 생성 및 DispatcherServlet을 통해 Bean / Filter 생성

※ Servlet Container

- Context Loader Listener와 DispatcherServlet으로 구성

- Context Loader Listener는 root-context.xml(applicationContext.xml)파일을 통해서 공통 컴포넌트들을 우선 스캔하여 생성

  (DB Connection이나 보안등을 위한 공통 Filter)

- DispatcherServlet은 개별 Thread를 생성하며, servlet-context.xml(presentation-layer.xml)파일을 통해서 Thread별로 Bean객체 및 Filter를 생성

 

※ ApplicationContext

- IoC을 위해서 ApplicationContext에 객체를 사전 등록

- ApplicationContext는 Singleton Pattern으로 생성되며, 필요한 곳에 DI

- root-applicationContext 와 servlet-applicationContext로 나뉘며 실행 순서는 root-applicationContext가 우선 실행

- root-applicationContext는 ContextLoaderListener에 의해 실행되고, @Service, @Repository등을 loading하고 DB 관련 객체(datasource) 생성

- servlet-applicationContext는 DispatcherServlet에 의해 실행되고, @Controller, @RestController를 loading하고 ViewResolver, Interceptor, MultipartResolver, HandlerMapping 객체를 생성

- servlet-applicationContext에서 root-applicationContext 객체 참조 가능

[그림 2] DispatcherServlet

 

※ Bean Factory

- 필요한 객체를 getBean()을 통해서 loading

- 클래스에 @Configuration 어노테이션을 사용하며, 해당 클래스의 메소드에 @Bean 어노테이션을 사용

- 클래스의 메소드를 호출시에 메모리에 loading하기 때문에 lazy-loading이라 함

 


3.8) Request Address에 따른 적절한 Controller 요청 (Handler Mapping)

- Get요청 => DispatcherServlet => Handler Mapping => 적절한 메소드 찾아서 실행


3.9) Response

- response가 html인 경우, ViewResolver가 관여하여, 파일의 prefix(접두사) & suffix(접미사)를 자동으로 붙여주어 파일 경로 정보를 return

- response가 data인 경우, MessageConverter가 단순 String 또는 json 형태의 객체로 return

[그림 3] Springboot 개념 간략도

 


  • warning: 

개발/프로그래밍 > 백엔드 > 스프링부트 개념정리(이론)

[2023.02.08 기준] - 해당 강의 무료 시청 가능

추후 강의 유/무료가 바뀌거나 강의 내용이 업데이트 될 수 있음


  • source:

https://www.inflearn.com/

 

인프런 - 미래의 동료들과 함께 성장하는 곳 | IT 정보 플랫폼

프로그래밍, 인공지능, 데이터, 마케팅, 디자인, 엑셀 실무 등 입문부터 실전까지 업계 최고 선배들에게 배울 수 있는 곳. 우리는 성장 기회의 평등을 추구합니다....

www.inflearn.com

https://getinthere.tistory.com/11

 

스프링부트 with JPA 3강 - Springboot 동작원리!

1. 스프링부트 동작원리 (1) 내장 톰켓을 가진다. 톰켓을 따로 설치할 필요 없이 바로 실행가능하다. (2) 서블릿 컨테이너 (3) web.xml -ServletContext의 초기 파라미터 -Session의 유효시간 설정 -Servlet/JSP

getinthere.tistory.com

 

728x90