Book/스프링부트 핵심가이드

[Spring] 스프링부트 개발 기초 지식

블로그 주인장 2023. 10. 18.

스프링부트 개발 지식

스프링부트 웹 애플리케이션 개발 프로젝트를 진행 할 때, 도움이 되는 개발 배경지식을 알아보겠습니다.


마이크로서비스 아키텍처(MSA)

  • Microservice Architecture
  • 서비스 규모를 작게 나누어 구성한 아키텍처를 뜻한다.
  • ex) 포털사이트 : 어플리케이션 하나에 여러 기능을 삽입하여 블로그, 카페, 메일 등을 기능별로 나눠서 개발한다.

  • 서버 간 통신
    • 하나의 서버가 다른 서버에 통신을 요청하는 것으로 1대는 서버, 1대는 클라이언트가 되는 구조이다.
    • ex) 사용자가 블로그 기능을 사용하기 위해 로그인 서비스를 거쳐야하는 상황
    • 가장 많이 사용되는 방식은 HTTP/HTTPS 방식이다.

스프링부트의 동작 방식

  • spring-boot-starter-web 모듈을 사용하면 기본적으로 톰캣(Tomcat)을 사용하는 스프링 MVC 구조를 기반으로 동작한다.

  • 서블릿(Servlet) : 클라이언트에 요청을 처리하고, 결과를 반환하는 자바 웹 프로그래밍 기술
    • 일반적으로 서블릿은 서블릿 컨테이너(Servlet Container)에서 관리한다.
  • 서블릿 컨테이너
    • 서블릿 인스턴스(Servlet Instance)를 생성하고 관리하는 역할을 수행하는 주체
    • 톰캣(Tomcat) : WAS의 역할과 서블릿 컨테이너의 역할을 수행하는 대표적인 컨테이너이다.
    • 특징
      • 서블릿 객체를 생성, 초기화, 호출, 종료하는 생명 주기를 관리
      • 서블릿 객체는 싱글톤 패턴으로 관리
      • 멀티 스레딩을 지원한다.
    • 스프링에서는 DispatcherServlet이 서블릿의 역할을 수행한다.
    • 일반적으로 스프링은 톰캣을 임베디드(embedded)하여 사용한다.
    • 서블릿컨테이너와 DispatcherServlet은 자동 설정된 web.xml의 설정값을 공유한다.
  • DispatcherSevlet의 동작 원리
    1. Http 요청(HttpServletRequest)이 들어오면 핸들러 매핑(Handler Mapping) 을 통해 요청 URI에 매핑된 핸들러를 탐색한다.  [핸들러 == 컨트롤러(Controller)]
    2. 핸들러 어댑터(HandlerAdpater)로 컨트롤러를 호출
    3. 핸들러 어댑터에 컨트롤러 응답이 돌아오면 ModelAndView로 응답을 가공해서 반환
    4. 뷰 형식으로 리턴하는 컨트롤러를 사용 시에는 뷰 리졸버(view Resolver)를 통해 뷰(view)를 받아 리턴한다.
  • 핸들러 매핑 : 요청 정보를 기준으로 어떤 컨트롤러를 사용할 지 선정하는 인터페이스
    • BeanNameUrlHanderMapping
      • 빈 이름을 URL로 사용하는 매핑 전략이다
      • 빈을 정의할 때 슬래시("/")가 들어가면 매핑 대상이 된다.
      • ex) @Bean("/hello")
    • ControllerClassNameHandlerMapping
      • URL과 일치하는 클래스 이름을 갖는 빈을 컨트롤러로 사용하는 전략이다.
      • 이름 중 Controller를 제외하고 앞부분에 작성된 suffix를 소문자로 매핑한다.
    • SimpleUrlHandlerMapping
      • URL 패턴에 매핑된 컨트롤러를 사용하는 전략
    • DefaultAnnotationHandlerMapping
      • 어노테이션으로 URL과 컨트롤러를 매핑하는 방법
  • 뷰 리졸버(View Resolver)
    • 뷰의 렌더링 역할을 담당한는 뷰 객체를 반환
    • 뷰가 없는 REST 형식의 @ResponseBody 사용 시에는 뷰 리졸버를 호출하지 않고 MessageConverter를 거쳐 JSON 형식으로 변환해서 응답한다.

  • MessageConverter
    • 요청과 응답에 대해 Body 값을 변환하는 역할을 수행한다.
    • 스프링 부트의 자동 설정 시에 HttpMessageConverter 인터페이스를 사용한다.
    • 해당 인터페이스를 기반으로 하는 구현체 클래스는 다양하다.
    • Content-Type을 참고해서 Converter를 선정한다.
    • 스프링 부트에서는 자동 설정이 되기 때문에 별도 설정이 필요하지 않다.


레이어드 아키텍처(Layered Architecture)

  • 어플리케이션의 컴포넌트를 유사 관심사를 기준으로 레이어로 묶어 수평적으로 구성한 구조를 의미한다.
  • 여러 방면에서 쓰이는 개념이며, 어떻게 설계하느냐에 따라 용어와 계층의 수가 달라진다.
  • 일반적으로 3계층 or 4계층 구성을 의미하고, 인프라(데이터베이스) 레이어의 추가 여부로 결정된다.

  1. 프리젠테이션 계층
    • 애플리케이션의 최상단 계층이며, 클라이언트의 요청을 해석하고 응답하는 역할
    • UI, API 제공
    • 별도의 비즈니스 로직을 포함하지 않아, 비즈니스 계층으로 요청을 위임하고 받은 결과를 응답하는 역할만 수행
  2. 비즈니스 계층
    • 애플리케이션이 제공하는 기능을 정의
    • 세부 작업을 수행하는 도메인 객체를 통해 업무를 위임하는 역할 수행
    • DDD(Domain-Driven Design) 기반의 아키텍처에서 비즈니스 로직을 도메인에 포함하기도 하고, 별도로 도메인 계층을 두기도 한다.
  3. 데이터 접근 계층
    • 데이터베이스에 접근하는 일련의 작업을 수행
  4. 레이어드 아키텍처 기반 설계
    • 각 레이어는 가장 가까운 하위 레이어의 의존성을 주입받는다.
    • 각 레이어는 관심사에 따라 묶이고, 다른 레이어의 역할을 침범하지 않는다.
      • 각 컴포넌트의 역할이 명확하므로, 코드의 가독성과 기능 구현에 유리
      • 코드의 확장성도 좋아진다.
    • 독립적으로 작성되면 다른 레이어와의 의존성을 낮춰 단위 테스트에 용이하다.

스프링 레이어드 아키텍처

  • Spring MVC : Model-View-Controller 구조
    • View,  Controller : 프리젠테이션 계층
    • Model : 비즈니스와 데이터 접근 계층 영역으로 구분 
    • 스프링 MVC 모델로 구현하기 위해 역할을 세분화한다.
      1. 비즈니스 계층에 엔티티(Entity) 같은 도메인 객체의 비즈니스 로직을 조합
      2. 데이터 접근 계층 : DAO(Spring Data JPA : Repository)를 배치하여 도메인을 관리한다.

  1. 프리젠테이션 계층
    • 인터페이스(UI : User Interface) 계층이라고 불리기도 한다.
    • 클라이언트와 접점이 된다.
    • 클라이언트로부터 데이터와 함께 요청을 받고, 처리 결과를 응답으로 전달하는 역할
  2. 비즈니스 계층
    • 서비스(Service)  계층이라고 불리기도 한다.
    • 핵심 비즈니스 로직을 구현하는 영역
    • 트랜잭션 처리 및 유효성 검사 등의 작업도 수행
  3. 데이터 계층
    • 영속(Persistence) 계층이라고 불리기도 한다.
    • 데이터베이스가 접근해야하는 작업을 수행
    • Spring Data JPA에서 DAO 역할을 리포지토리(Repository)가 수행하기 때문에 리포지토리로 대체 가능하다.
  4. 구현 시 참고 사항
    • 가장 중요한 부분 : 비즈니스 계층 영역으로, 비즈니스 로직을 어디서 담당할지 결정하고 설계하는 것이 좋다.
    • 비즈니스 로직은 도메인 계층에서 담당하는 것이 일반적이다.
    • JPA를 사용하면 @Entity를 정의한 클래스가 도메인 객체가 되며, 해당 클래스에서 설계하는 것이 좋다.
    • 서비스 레이어에서 비즈니스 로직을 담당하는 경우도 있으므로 역할과 책임을 잘 구분해서 설계해야한다.

디자인 패턴(Design Pattern)

  • 소프트웨어를 설계 시에 자주 발생하는 문제들을 해결하기 위해 고안된 해결책이다.
  • 패턴(Pattern) : 개발에서 발생하는 문제는 유사한 경우가 많고, 해결책도 동일하게 적용할 수 있다는 의미를 내포한다.

디자인 패턴의 종류

  • ex) GOF 디자인 패턴
    • Gang of Four : 디자인 패턴을 구체화 하고 체계화하여 분류한 4명의 인물들을 의미한다.

  1. 생성 패턴
    • 객체 생성에 사용되는 패턴
    • 객체를 수정해도 호출부가 영향을 받지 않게 한다.
    • 생성 패턴의 종류
      1. 추상 팩토리 : 구체적인 클래스를 지정하지 않고, 상황에 맞는 객체를 생성하기 위한 인터페이스를 제공하는 패턴
      2. 빌더 : 객체의 생성과 표현을 분리해 객체를 생성하는 패턴
      3. 팩토리 메서드 : 객체 생성을 서브클래스로 분리해서 위임하는 패턴
      4. 프로토타입 : 원본 객체를 복사하여 객체를 생성하는 패턴
      5. 싱글톤 : 한 클래스마다 인스턴스를 하나만 생성하여, 인스턴스가 하나임을 보장하고, 어느 곳에서도 접근할 수 있게 제공하는 패턴
  2. 구조 패턴
    • 객체를 조합해서 더 큰 구조를 만드는 패턴이다.
    • 구조 패턴의 종류
      1. 어댑터 : 클래스의 인터페이스를 의도하는 인터페이스로 변환하는 패턴
      2. 브릿지 : 추상화 구현을 분리해서 각각 독립적으로 변형하게 하는 패턴
      3. 컴포지트 : 여러 객체로 구성된 복합 객체와 단일 객체를 클라이언트에서 구별 없이 다루는 패턴
      4. 데코레이터 : 객체의 결합을 통해 기능을 동적으로 유연하게 확장할 수 있게 하는 패턴
      5. 퍼사드 : 서브시스템의 인터페이스 집합들에 하나의 통합된 인터페이스를 제공하는 패턴
      6. 플라이웨이트 : 특정 클래스의 인스턴스 한 개를 가지고 여러 개의 '가상 인스턴스'를 제공할 때 사용하는 패턴
      7. 프락시 : 특정 객체를 직접 참조하지 않고 해당 객체를 대행(프락시) 하는 객체를 통해 접근하는 패턴
  3. 행위 패턴
    • 객체 간의 알고리즘이나 책임 분배에 관한 패턴이다.
    • 객체 하나로는 수행할 수 없는 작업을 여러 객체를 이용해서 작업 분배한다.
    • 결합도 최소화를 고려할 필요가 있다.
    • 행위 패턴의 종류
      1. 책임 연쇄 : 요청 처리 객체를 집합으로 만들어 결합을 느슨하게 만드는 패턴
      2. 커맨드 : 실행될 기능을 캡슐화해서 주어진 여러 기능을 실행하도록 클래스를 설계하는 패턴
      3. 인터프리터 : 주어진 언어의 문법을 위한 표현 수단을 정의하고, 해당 언어로 구성된 문장을 해석하는 패턴
      4. 이터레이터 : 내부 구조를 노출하지 않으면서, 해당 객체의 집합 우너소에 순차적으로 접근하는 방법을 제공하는 패턴
      5. 미디에이터 : 한 집합에 속한 객체들의 상호작용을 캡슐화하는 갹채룰 정의한 패턴
      6. 메멘토 : 객체의 상태 정보를 저장하고, 필요에 따라 상태를 복원하는 패턴
      7. 옵저버 : 객체의 상태 변화를 관찰하는 관찰자들, 옵저버 목록을 객체에 등록해 상태가 변할 때마다 메서드 등을 통해 객체가 직접 옵저버에게 통지하게 하는 디자인 패턴
      8. 스테이트 : 상태에 따라 객체가 행동을 변경하게 하는 패턴
      9. 스트래티지 : 행동을 클래스로 캡슐화해서 동적으로 행동을 바꿀 수 있게 하는 패턴
      10. 템플릿 메서드 : 일정 작업을 처리하는 부분을 서브클래스로 캡슐화해서 전체 수행 구조는 바꾸지 않으면서 특정 단계만 변경해서 수행하는 패턴
      11. 비지터 : 실제 로직을 가지고 있는 객체(Visitor)가 로직을 적용할 객체(element)를 방문하며 실행하는 패턴

REST API

  1. REST의 의미
    • Representational State Transfer
    • 월드 와이드 웹(WWW)과 같은 분산 하이퍼미디어 시스템 아키텍처의 형식 중 하나이다.
    • 주고 받은 자원(Resource)에 이름을 규정하고 URI에 명시해 HTTP 메서드(GET, POST, PUT, DELETE)를 통해 해당 자원의 상태를 주고받는 것을 의미한다.
  2. REST API의 의미
    • API : Application Programming Interface, 애플리케이션에서 제공하는 인터페이스를 의미한다.
    • REST 아키텍처를 따르는 시스템/애플리케이션 인터페이스라고 볼 수 있다.
    • REST 아키텍처를 구현하는 웹 서비스를 'RESTful하다' 라고 표현한다.
  3. REST의 특징
    1. 유니폼 인터페이스
      • "일관된 인터페이스" 를 의미
      • REST 서버는 HTTP 표준 전송 규약을 따르기에, 플랫폼 및 기술에 종속되지 않고 타 언어, 플랫폼, 기술 등과 호환하여 사용할 수 있다는 것을 의미한다.
    2. 무상태성
      • "서버에 상태 정보를 따로 보관하거나 관리하지 않는다" 는 의미이다.
      • 서버는 클라이언트가 보낸 요청에 대해 세션이나 쿠키 정보를 별도로 보관하지 않는다.
      • 하나의 클라이언트가 여러 요청을 보내든, 여러 클라이언트가 각각 하나의 요청을 보내든 개별적으로 처리한다.
      • 서버가 불필요한 정보를 관리하지 않으므로, 비즈니스 로직의 자유도가 높고 설계가 단순하다.
    3. 캐시 가능성
      • HTTP 표준을 그대로 사용하므로, HTTP의 캐싱 기능을 적용할 수 있다.
      • 응답과 요청이 모두 캐싱이 가능한지(Cacheable) 명시가 필요하다.
      • 캐싱이 가능한 경우 클라이언트에서 캐시에 저장해두고 같은 요청에 대해서는 해당 데이터를 가져다가 사용한다.
      • 서버의 트랜잭션 부하가 줄어 효율적이며, 사용자 입장에서 성능이 개선된다.
    4. 레이어 시스템
      • 네트워크 상의 여러 계층으로 구성될 수 있다.
      • 서버의 복잡도와 관계없이 클라이언트는 서버와 연결되는 포인트만 알면 된다.
    5. 클라이언트-서버 아키텍처
      • API를 제공하고 클라이언트는 사용자 정보를 관리하는 구조로 분리해 설계한다.
      • 해당 구성은 서로에 대한 의존성을 낮추는 기능을 한다.
  4. REST의 URI 설계 규칙
    1. URI의 마지막에는 '/' 를 포함하지 않는다.
      • ex) http://localhost.com/product 
    2. 언더바(_)는 사용하지 않는다. 대신 하이픈(-)을 사용한다.
      • ex) http://localhost.com/product-select-name
    3. URL에는 행위(동사)가 아닌 결과(명사)를 포함한다.
      • ex) http://localhost.com/product/12345
      • 행위는 HTTP 메서드로 표현할 수 있어야 한다.
    4. URI는 소문자로 작성해야한다.
      • URI 리소스 경로에는 대문자 사용을 피하는 것이 좋다.
      • 일부 웹 서버의 운영체제는 리소스 경로 부분의 대소문자를 다른 문자로 인식하기 때문이다.
      • RFC3986은 URI 문법 형식을 정의하는데, 호스트의 구성요소를 제외하고 URI의 대소문자를 구분해서 정의하고 있다.
    5. 파일의 확장자는 URI에 포함하지 않는다.
      • HTTP에서 제공하는 Accept 헤더를 사용하는 것이 좋다.
반응형

댓글