본문 바로가기
스프링부트 핵심가이드

[북스터디] 스프링 부트 핵심가이드 (ch2~ch4)

by ddahu 2023. 4. 24.

chapter 2  개발에 앞서 알면 좋은 기초 지식

ch2 에서는 스프링부트를 개발하기 앞서 알고 있으면 좋은 기초지식들에 관하여 작성되어있다.

서버간의 통신 , 스프링 부트 동작 방식 , 디자인 패턴 , REST API 이러한 기초지식을 바탕으로 작성되어있지만 내용의 위주를 한번 쭉 읽어봤을때 내가 알고있던 기초 지식은 정말...기초 였다는걸 알게 되어 큰 도움이 되었다는 걸 느끼는 chapter였다.


- 서버 간 통신 

어떤 포털 사이트를 하나의 서비스 단위로 개발한다고 가정 할때 , 블로그 ,카페 , 메일 등의 기능들을 하나의 애플리케이션에서 통합했을때 이 서버를 업데이트 하거나 애플리케이션을 유지보수 할때 사이트 전체를 닫고 '사이트 작업 중입니다 ' 라는 팻말을 걸고 작업 해야한다 . 이 같은 문제를 해결하기 위해 나온 것이 마이크로 아키텍쳐 ( MSA : Microservice Architecture)  이다.

 

 

- 마이크로 아키텍쳐 (MSA : Microservice Architecture) 

한 웹앱이 하나의 단일 파일이 아니라 모듈 기능의 따라 나뉘어 있는 형태로 이루어 져 있는 형식을 마이크로 아키텍쳐(MSA)라고 한다.

 

만약 위 예시로 (블로그 , 카페 ,메일) 의 포털사이트 웹앱에서 단일 서비스 아키텍쳐 일경우에 블로그의 글쓰기, 댓글 쓰기 , 클릭 등등 다양한 기능들이 하나의 거대한 단일 파일로 존재 한다면 유지보수를 하거나 일부 기능들을 업데이트 수정 할때 전체를 수정해야 하는것이다.

 

이러한 문제를 마이크로 아키텍처 구조로 이용한다면  각각의 기능별로 독립적인 애플리케이션을 개발하게 된다면 필요한 부분만 접근하여 유지보수 및 업데이트 수정이 가능하게 된다.

 

단 , 마이크로 아키텍처 구조를 사용한다면 각 서비스 간에 통신을 해야하는 경우가 발생한다 . 이러한 상황을 '서버 간 통신 ' 이라고 한다.

 

예를 들자면 , 사용자가 블로그 기능을 사용하기 위해 로그인 서비스를 거쳐야만 하는 상황이 필요로 하다.

 

이러한 서버 간 통신은 한서버가 다른 서버에 통신을 요청하는 것을 의미 하며 , 한 대는 서버 , 다른 한대는 클라이언트가 되는 구조를 말하며 몇가지 프로토콜에 의해 다양한 통신 방식을 적용할 수 있지만 가장 많이 사용 되는 방식은 HTTP /HTTPS 방식이다.

 

이서적 에서는 HTTP/ HTTPS 방식을 기반으로 소개하고 있다.

 


2. 스프링 부트의 동작 방식

스프링 부트에서 기본적으로 톰캣을 사용하는 스프링 MVC 구조를 기반으로 동작한다.

스프링 부트의 동작 구조

해당 그림은 스프링 부트 동작의 구조 이다.

해당 그림에서 스프링 부트는 서블릿(Servlet) 이 클라이언트의 요청을 처리하고 결과를 반환하는 기술 이다.

 

기본적으로 서블릿이라는 개념은 정말 많은 개념을 가지고 있지만 스프링 부트가이드 서적을 기반으로 작성하자면

 

  1. 서블릿(Servlet)
    서블릿은 서블릿 컨테이너에서 관리하고 서블릿 은 클라이언트의 요청을 처리하고 결과를 반환하는 자바 웹프로그래밍 기술 이다.
  2. 서블릿 컨테이너 특징 3가지
    1. 서블릿 객체를 생성, 초기화, 호출 종료하는 생명주기를 관리한다.
    2. 서블릿 객체는 싱글톤 패턴으로 관리된다.
    3. 멀티 스레딩을 지원함

스프링에서는 DispatcherServlet 이 서블릿 의 역할을 수행한다.

스프링은 톰캣을 임베드(embed) 해 사용한다. 그렇기 때문에 서블릿 컨테이너와 DispatcherServlet은 자동 설정된 web.xml의 설정 값을 공유한다.

 

스프링 부트의 동작 구조 이미지를 보고 내용을 설명하자면

  1. DispatcherServlet으로 요청(HttpServletRequest)가들어오면 DispatcherServlet은 핸들러 매핑(Handler Mapping)을 통해 요청 URI에 매핑된 핸들러를 탐색한다. 여기서 핸들러는 컨트롤러(Contrller)를 의미.
  2. 핸들러 어댑터 (HandlerAdapter)로 컨틀로러르 호출
  3. 핸들러 어댑터에 컨트롤러의 응답이 돌아오면 ModelAndView로 응답을 가공해 반환
  4. 뷰 형식으로 리턴하는 컨트롤러를 사용할 때는 뷰 리졸버(View Resolver)를 통해 뷰를 반환 

주로 @RestController 를 사용하며 이 책에서도 @RestController를 사용 한다고 나와있다.

 

위 그림은 책에 내용과 좀 다르지만 MessageConverter가 (@Controller + @ResponseBody) 라고 생각 하면 이해하기가 쉽다.

 MessageConverter가 (@Controller + @ResponseBody) 는 요청과 응답에 대해 JSON 형태의 Body 값을 반환하는 역할을 수행 한다.

 

위 그림을 설명하면 

Client 는 URI 형식의 웹서비스에 Request 를 요청을 전송

Hadler Mapping 을 지나 RestController 에 해당 요청을 처리하고 데이터를 Response 해주는 형식이다.


3. 레이어드 아키텍쳐

레이어드 아키텍쳐에대해 요약 하자면 각 애플리케이션의 컴포넌트를 관심사(?) 를 기준으로 레이어로 묶어 수평적 구성한 구조라고 책은 정의하고있다.

 

내가 이 부분을 읽었을때 그냥 이해한다고 생각한게 각계층마다 개념을 정리하여 묶어 군집화시켜 계층화 시킨거라고 생각을 하였다.

 

각 계층은 다음과 같이 구부된다

  1. 프레젠테이션 계층
    1. 애플리케이션의 최상단 계층으로 , 클라이언트의 요청을 해석하고 응답하는 역할이다.
    2. UI 나 API를 제공
    3. 프레젠테이션 계층은 별도의 비즈니스 로직을 포함하고 있지 않으므로 비즈니스 계층으로 요청을 위임하고 받은 결과를 응답하는 역할만 수행
  2. 비즈니스 계층
    1. 애플리케이션이 제공하는 기능을 정의하고 세부작업을 수행하는 도메인 객체를 통해 업무를 위임하는 역할을 수행
    2. DDD(Domain-Driven Design) 기반의 아키텍쳐에서는 비즈니스 로직에 도메인이 포함되기도 하고, 별도로 도메인 계층을 둠.
  3. 데이터 접근 계층
    1. DB에 접근하는 일련의 작업을 수행

스프링의 레이어드 아키텍처

 

위 그림은 스프링 레이어드 아키텍쳐이다

 

위에 설명한 구조로 3계층 구조로 만들어져 있다.

 

실제 구현을 해본다면 스프링부트를 통해서 첫 개발을 시작할때는 아무것도 없는 구조이다. 실제 프로그래밍을 해보면 자신도 모르게 MVC 패턴을 구현하는 모습이 보이게 된다...

 

Spring MVC 는 Model - View -Controller 이며 

해당 그림에서는  프레젠테이션 계층이 View - Controller 이며 Model은 데이터 접근 계층에 해당된다.

실제 프로그래밍을 하면서  Service / Application 에 해당 되는 부분은 비즈니스 계층에 해당된다.

 

이런식으로 계층적으로 구분하여 프로그래밍을 한다면 추후 유지보수 와 복잡한 로직이 헷갈리지 않게 된다.

 


4. 디자인 패턴

디자인 패턴은 정처기를 준비하면서 정말..정말.. 많이 봐왔던 부분이다..!

 

 

디자인 패턴의 경우 GoF(Gang of Four) 패턴으로 분류되어 있다.(생.구.행)

.

  • 생성 패턴
    • 객체 생성에 사용되는 패턴으로 , 객체를 수정해도 호출부가 영향을 받지 않게 한다.
  • 구조 패턴
    • 객체를 조합해서 더 큰 구조를 만드는 패턴
  • 행위 패턴
    • 객체 간의 알고리즘이나 책임 분배에 관한 패턴
    • 객체 하나로는 수행할 수없는 작업을 여러 객체를 이용해 작업을 분배합니다. 결합도 최소화를 고려할 필요가 있음.

-생성 패턴

 

추상 팩토리 : 구체적인 클래스를 지정하지 않고 상황에 맞는 객체를 생성하기 위한 인터페이스를 제공하는 패턴

빌더 : 객체의 생성과 표현을 분리해 객체를 생성하는 패턴

팩토리 메서드 : 객체 생성을 서브클래스로 분리해서 위임하는 패턴

프로토타입 :  원본 객체를 복사해 객체를 생성하는 패턴

싱글톤 : 한 클래스마다 인스턴스를 하나만 생성해서 인스턴스가 하나임을 보자하고 어느 곳에서도 접근할 수 있게 제공하는 패턴

 

- 구조 패턴

 

어댑터 :  클래스의 인터페이스를 의도하는 인터페이스로 변환하는 패턴

브리지 : 추상화와 구현을 분리해서 각각 독립적으로 변형케 하는 패턴

컴포지트 : 여러 객체로 구성된 복합 객체와 단일 객체를 클라이언트에서 구별없이 다루는 패턴

퍼사드 : 서브시스템의 인터페이스 집하들에 하나의 통합된 인터페이스를 제공하는 패턴

플라이웨이트 : 특정 클래스의 인스턴스 한 개를 가지고여러 개의 ' 가상 인스턴스'를 제공할 대 사용하는 패턴

프락시 : 특정 객체를 직접 참조하지 않고 해당 객체를 대행 하는 객체를 통해 접근하는 패턴

 

- 행위패턴

 

책임 연쇄 : 요청 처리 객체를 집합으로 만들어 결합을 느슨하게 만드는 패턴

커맨드 : 실행될 기능을 캡슐화 해서 주어진 여러기능을 실행하도록 클래스를 설계하는 패턴

인터프리터  : 주어진 언어의 문법을 위한 표현수단을 정의하고 해당 언어로 구성된 문장을 해석 하는 패턴

이터레이터 : 내부 구조를 노출하지 않으면서 해당 객체의 집합원소에 순차적으로 접근하는 방법을 제공하는 패턴

미디에이터 : 한 집합에 속한 객체들의 상호 작용을 캡슐화하는 객체를 정의하는 패턴

메멘토 : 객체의 상태 정보를 저장하고 필요에 따라 상태를 복원하는 패턴

옵저버 : 객체의 상태 변화를 관찰하는 관찰자들 , 즉 업저버 목록을 객체에 등록해 상태가 변할대마다 메서드 등을 통해 객체가 직접 옵저버에게 통지하게 만드는 디자인 패턴

스테이트: 상태에 따라 객체가 행동을 변경하게 하는 패턴
스트래티지: 행동을 클래스로 캡슐화해서 동저긍로 행동을 바꿀 수 있게 하는 패턴
탬플릿 메서드: 일정 작업을 처리하는 부분을 서브클래스로 캢휼화해서 전체 수행 구조는 바꾸지 않으면서 특정 단계만 변경해서 수행하는 패턴
비지터: 실제 로직을 가지고 있는 객체(visiort)가 로직을 적용할 객체(element)를 방문하며 실행하는 패턴

 


5. REST API

 

REST API는 대중적으로 가장 많이 사용되는 애플리케이션 인터페이스 이다 . REST 란 'Representaional State Transfer' 의 약자로 주고 받는 URI에 명시해 HTTP 메서드 (GET , POST , PUT , DELETE)를 통해 해당 자원의 상태를 주고 받는 것이다. 대표적으로 CRUD 를 구현하기 위해서 정말 많이사용한다 (CREATE , READ , UPDATE , DELETE)

 

 

 

- REST 의 특징과 설계 규칙

 

  • 유니폼 인터페이스
    • REST 서버는 HTTP표준 전송 규약을 따르기 때문에 어떤 프로그래밍 언어로 만들어졌느냐와 상관없이 종속되지 않고 호환해 사용될수 있음을 의미
  • 무상태성
    • 서버에 상태 정보를 따로 보관하거나 관리 하지 않는 다라는 의미를가진다. 이러한 의미를 가져 서비스는 서버가 불필요한 정보를 관리하지 않으므로 비즈니스 로직의 자유도가 높고 설계가 단순해진다.
  • 캐시 가능성
    • REST는 HTTP 표준을 그대로 사용하므로 HTTP의 캐싱 기능을 적용 가능. 이 기능을 이용하기 위해서는 응답과 요청이 모두 캐싱 가능한지(Cacheable) 명시가 필요하며, 캐싱이 가능한 경우 클라이언트에서 캐시에 저장해두고 같은 요청에 대해서는 해당 데이터를 가져다 사용. 이 기능을 사용하면 서버의 트랜잭션 부하가 줄어 효율적이며 사용자 입장에서 성능이 개선됨.
  • 레이어 시스템
    • REST 서버는 네트워크 상의 여러 계층으로 구성될수 있다 . 그러나 서버의 복잡도와 관계없이 클라이언트는 서버와 연결되는 포인트만 알면된다.
  • 클라이언트 - 서버 아키텍쳐
    •  REST서버는 API를 제공하고 클라이언트는 사용자 정보를 관리하는 구조로 분리해 설계한다. 이 구조성은 서로에 대한 의존성을 낮추는 기능을 한 다.

 

-REST 의 URI 설계 규칙

  • URL 규칙
    • URI의 마지막에는 '/' 를 포함하지않는다.
      • 옳은 예시 ) http://localhost/product
      • 잘못된 예시 ) http://localhost/product/
    • 언더바(_)는 사용하지않고 대신 하이폰(-)를 사용
      • 하이폰은 리소스의 이름이 길어지면 사용한다.
      • 옳은 예시 ) http://localhost/provider-company-name
      • 잘못된 예시 ) http://localhost/provider_company_name
    • URL에는 행위(동사)가아닌 명사를 포함
      • 옳은 예시 ) http://localhost/product/123
      • 잘못된 예시 ) http://localhost/product/delete-product/123
      • 행위는 HTTP 메서드로 표현할 수 있어야 한다.
    • URI는 소문자
      • URI는 소문자로 작성.
      • URI 리소스 경로에는 대문자 사용을 피할 것.
        (일부 웹 서버의 운영체제는 리소스 경로 부분의 대소문자를 다른 문자로 인식하기 때문. 이러한 이유로 RFC3986은 URI 문법 형식을 정의하고 있는데, 호스트의 구성요소를 제외하고 URI의 대소문자를 구분해서 정의)
    • 파일의 확장자는 URI에 포함하지 않는다.
      • HTTP에서 제공하는 Accept 헤더를 사용

chapter 3 개발환경구성 / chapter 4 스프링부트 애플리케이션 개발하기

 

이 챕터 두개는 딱히 요약 할 부분이 없다...

그나마 요약하자면 

 

ch3 : InteliJ Ultimate 추천  , 환경변수 설정 

ch4 : 스프링공식 사이트에서 spring Initializr 를 사용 혹은 인텔리제이 얼티밋을 사용하면 인텔리제이에서 생성 가능

생성 시 의존성 추가 (Lombok , Spring Web ) 추천 등등등... 

 

이미 한번 스프링부트를 개발한 사람이라면 쓰윽 한번만 읽어보면 될거 같다.