- 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에 접근 시, 서버 부하가 심해짐
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
※ 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 객체 참조 가능
※ 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
- warning:
개발/프로그래밍 > 백엔드 > 스프링부트 개념정리(이론)
[2023.02.08 기준] - 해당 강의 무료 시청 가능
추후 강의 유/무료가 바뀌거나 강의 내용이 업데이트 될 수 있음
- source:
인프런 - 미래의 동료들과 함께 성장하는 곳 | 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
'Dev > Spring.SpringBoot' 카테고리의 다른 글
[SpringBoot] [Inflearn - 무료] 스프링부트 시큐리티 & JWT 강의 (Section 1) (0) | 2023.02.17 |
---|---|
[SpringBoot] [Inflearn - 무료] 스프링부트 시큐리티 & JWT 강의 (Section 0) (0) | 2023.02.08 |
[DataSource] BasicDataSource Configuration Parameters 정보 (0) | 2022.11.10 |
JDBC Internal - 타임아웃의 이해 (0) | 2022.11.10 |
[DBCP] Commons DBCP 이해하기 (Common-dbcp, dbcp2) (0) | 2022.11.04 |