본문 바로가기

공부/백엔드

[스프링 부트 핵심 가이드] 1~3 : 스프링부트, MVC, 디자인패턴

반응형

* spring docs : https://docs.spring.io/spring-framework/docs/4.0.x/spring-framework-reference/html/

1. 스프링 부트란?

먼저 스프링부트의 기반이 되는 스프링은 자바에서 많이 사용하는 경량 프레임워크로 엔터프라이즈급 애플리케이션을 개발할 수 있으며 여러 복잡한 처리를 프레임워크에 위임하고 비즈니스 로직을 구현하는데 집중할 수 있습니다.

주로 웹 서비스를 개발할 때 사용하며 그외에도 스프링으로 개발할 수 있는 것으로 Microservice, Reactive, Cloud, Serverless, Event Driven, Batch 등이 있습니다.

 

1-1. IoC (제어역전)

: 객체의 제어권이 넘어간 것을 뜻하며, 객체를 사용하기 위해 직접 생성(new)하지 않고 객체의 생명주기 관리를 스프링 컨테이너에 위임합니다.

 

 

- DI (의존성 주입)

: 외부 컨테이너가 객체를 생성하여 주입하는 것 (@Autowired)

 

주입 방법

1. 생성자: 어노테이션 생략 가능, 레퍼런스 객체 없이는 초기화 불가능하여(의존성 객체가 주입되어야 객체가 생성됨) 권장하는 방법

Service service;
@Autowired
public Constructor(Service service) {
	this.service = service;
}

 

2. 필드 객체 선언

@Autowired
Service service;

 

3. setter

Service service;

@Autowired
public void setService(Service service) {
	this.service = service;
}

 

 

- AOP

: 관점(Aspect)를 기준으로 묶어 개발한다. 코드에는 핵심 기능(비즈니스 로직의 주 기능)과 부가 기능(로깅 처리 및 트랜잭션 처리)이 있는데, 다른 기능에서도 부가 기능은 동일한 기능을 수행하며 중복 코드가 발생할 수 있다.

-> 이러한 부가 기능은 로직이 수행되기 전/후에 수행되면 되므로 공통으로 처리할 수 있게 모듈화하여 삽입한다.

장점: 재사용 가능, 비즈니스 로직 집중

*프록시 패턴: 원래 객체가 생성되기 전 또는 후에도 다른 객체가 대신 작업을 수행할 수 있는 패턴

 

 

1-2. 스프링 프레임워크의 구조

Core Container

- Beans/Core : IoC 및 종속성 주입 기능 등 프레임워크의 기본 부분

- Context : Beans 모듈의 기능을 상속하고 이벤트 전파, 리소스 로딩 및 서블릿 컨테이너 등을 통한 투명한 컨텍스트 생성에 대한 지원

- spEL : 스프링 표현언어로 스프링 어디에서든 쓸 수 있는 표현식 (#{}, ${})

 

Data Access/Intergration

- JDBC : 데이터베이스와의 연결, 쿼리 실행, 결과 처리 등의 작업을 수행할 수 있도록 Java 프로그램에 표준화된 방법을 제공하며 데이터베이스별 코드를 수정할 필요성을 없애기 위한 추상화 계층을 제공한다.

- ORM : JPA, JDO, Hibernates 등 직접 SQL을 작성하지 않고 데이터를 객체화하는 기술

- OXM : JAXB, Castor, XMLBeans, JiBX 및 XStream에 대한 객체/XML 매핑 구현을 지원하는 추상화 계층을 제공

- JMS : 메시지를 생성하고 소비하는 기능

- Transactions : 프로그래밍 방식 및 선언적 트랜잭션 관리를 지원

 

1-3. 스프링부트

스프링은 복잡한 설정을 bean 등록을 통해 직접 해줘야 하며 설정이 복잡해진다. -> 따로 개발자가 설정할 필요없이 지원해주는 것이 스프링부트이다.

 

스프링 부트의 특징

1. 의존성 관리

: 여러 모듈 간 의존성 관리를 직접 해줄 필요없이 spring-boot-starter-*그룹에서 호환되는 버전의 모듈 조합들을 제공한다.

- spring-boot-start의 종류: web(tomcat), test(JUnit), jdbc(hikariCP), security, jpa, cache, parent(start간 의존성)

 

2. 자동 설정

: 추가된 라이브러리를 사용하기 위한 환경 설정을 자동으로 해준다.

@SpringBootApplication

  - @SpringBootConfiguration

  - @EnableAutoConfiguration: spring.factories 파일의 Auto Configure 항목이 조건에 맞으면 빈에 등록

  - @ComponentScan: @Component(Service, Controller, Repository 등) 객체를 bean으로 등록

 

3. 내장 WAS

: spring-boot-starter-web 톰캣 내장

 

4. 모니터링

: spring actuator

 


2. 기초 지식

2-1. 서버 간 통신

단일 서버 내에서는 메서드 호출 등으로 자원을 사용할 수 있지만 다른 서버와 통신해야 하는 경우가 있다.

예를 들면 MSA 환경에서 분리된 다른 서버에서 호출될 수 있다.

 

MSA : 서비스 단위를 잘게 쪼갠 아키텍처로, 한 서비스에 여러 기능이 있고 규모가 커지면 기능별로 나누어 개발하게 된다.

 

이때 호출하는 쪽은 클라이언트가 되며 주로 HTTP/HTTPS 프로토콜으로 통신한다.

 

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

서블릿 컨테이너: 클라이언트의 요청을 처리하고 결과를 반환하는 서블릿을 관리하는 컨테이너

  • 톰캣은 WAS + 서블릿 컨테이너
  • 서블릿 객체의 생명주기(생성, 초기화, 호출, 종료)를 관리한다.
  • 서블릿 객체는 싱글톤 패턴으로 관리된다.
  • 멀티 스레딩 지원

Dispatcher Servlet : 요청이 들어오면 전달하여 알맞은 처리를 하고 ModelAndView / View 리턴

-> HandlerMapping에서 요청(uri)에 매핑된 Handler(Controller)를 탐색

-> HandlerAdapter가 컨트롤러 호출

1)-> ModelAndView 반환 or ViewResolver를 통해 View를 받아 반환

2)-> MessageConverter에서 HTTP 응답 반환 (뷰가 아닌 REST API 기능에 집중해 body에 json 값을 리턴)

 

HandlerMapping 매핑 전략

1. BeanNameUrl : 슬래시("/")가 들어간 빈의 이름을 URL로 사용 (@Bean("/"))

2. ControllerClassName : URL과 일치하는 클래스 이름을 간는 빈을 컨트롤러로 사용 (**Controller)

3. SimpleUrl : URL 패턴에 매핑된 컨트롤러를 사용

4. DefaultAnnotation : 어노테이션으로 URL과 컨트롤러를 매핑

 

2-3. 레이어드 아키텍처

레이어드 아키텍처(MVC) : 컴포넌트를 유사 관심사 기준으로 레이어로 묶어 수평적으로 구성 (<-> D.D.D)

3계층 : 프레젠테이션, 비즈니스, 데이터 접근 (+데이터베이스)

  • 각 레이어는 가장 가까운 하위 레이어 1개의 의존성을 주입받는다.
  • 각 레이어는 다른 레이어 역할을 침범하지 않는다.
  • 장점: 코드 가독성 증가, 확장성 유리, 의존성이 낮아 단위테스트 유리

 

프레젠테이션 계층 (Controller)

: 최상위에서 클라이언트의 데이터와 함께 요청을 받고 처리 후, 응답

- UI, API 등 제공

- 비즈니스 로직을 비즈니스 계층에 요청하여 받은 결과를 응답한다.

 

비즈니스 계층 (Service)

: 비즈니스 로직을 정의하고, 세부 작업(DB 접근)을 수행하는 도메인 객체에 업무를 위임

- 트랜잭션 처리, 유효성 검사

- DDD에서는 비즈니스 로직에 도메인이 포함되기도 함

- JPA를 사용하는 경우, @Entity가 붙은 도메인 객체에서 비즈니스 로직을 작성

 

데이터 접근 계층 (Dao / Repository)

: 데이터베이스에 접근하는 작업 수행, 도메인 관리

 

2-4. 디자인 패턴

디자인 패턴: 소프트웨어 설계 시 발생하는 문제를 해결하기 위한 패턴

 

<<GoF 디자인 패턴>>

생성 패턴: 객체 생성에 사용하는 패턴으로 생성 및 수정해도 프로그램 구조에 영향을 받지 않게 한다.

  • 추상 팩토리: 상황에 맞게 클래스의 객체를 생성하는 인터페이스를 제공하는 패턴으로 추상화하여 여러 객체의 모음을 생성할 수 있다.
  • 빌더: 객체의 생성과 표현을 분리해 생성하는 패턴으로 각각의 생성자 없이 다양한 구성의 인스턴스를 만들 수 있다.
  • 팩토리 메서드: 객체 생성을 서브 클래스로 분리하여 위임하는 패턴
  • 프로토타입: 원본 객체를 복사하여 생성하는 패턴
  • 싱글톤: 한 클래스에 인스턴스를 하나만 생성할 수 있고(private 생성자) 어디서든(static) 사용할 수 있는 패턴

구조 패턴: 객체를 조합해서 더 큰 구조를 만드는 패턴

  • 어댑터: 인터페이스를 다른 인터페이스로 변환하는 패턴으로 기존 인터페이스 수정없이 호환 가능하게 해준다.
    • ex) InputStreamReader, HandlerAdapter
  • 브리지: 한 클래스를 추상화와 구현 클래스로 분리해서 각각 독립적으로 개발할 수 있게 하는 패턴
    • 추상화: 구현 객체를 인스턴스로 가지고 실제 작업을 수행
    • 구현: 구현 클래스들에 공통적인 메서드를 선언하는 인터페이스
    • 색이 있는 도형을 Color와 Shape로 각각 인터페이스로 만들어 독립적으로 확장할 수 있게 한다. 
    • 한쪽을 변경해도 서로에게 영향을 주지 않아 플랫폼 독립적인 클래스들과 앱들을 만들 수 있다.
  • 컴포지트: 여러 객체로 구성된 복합 객체와 단일 객체를 클라이언트에서 구별없이 다루는 패턴
  • 데코레이터: 객체의 결합을 통해 기능을 동적으로 유연하게 확장할 수 있게 하는 패턴
  • 퍼사드: 서브시스템의 인터페이스 집합들에 하나의 통합된 인터페이스를 제공하는 패턴
  • 플라이웨이트: 특정 클래스의 인스턴스 한 개를 가지고 여러 개의 가상 인스턴스를 제공할 때 사용하는 패턴
  • 프락시: 특정 객체를 직접 참조하지 않고 해당 객체를 대행(프락시)하는 객체를 통해 접근하는 패턴

 

행위 패턴: 객체 간의 알고리즘이나 책임 분배 - 여러 객체로 책임을 나눈다.

  • 책임 연쇄: 요청 처리 객체를 집합으로 만들어 결합을 느슨하게 만드는 패턴
  • 커맨드: 실행될 기능을 캡슐화해서 주어진 여러 기능을 실행하도록 클래스를 설계
  • 인터프리터: 주어진 언어의 문법을 위한 표현 수단을 정의하고 해당 언어로 구성된 문장을 해석하는 패턴
  • 이터레이터: 내부 구조를 노출하지 않으며 해당 객체의 집합 원소의 순차적으로 접근하는 방법을 제공
  • 미디에이터: 한 집합에 속한 객체들의 상호작용을 캡슐화하는 객체를 정의한 패턴
  • 메멘토: 객체의 상태 정보를 저장하고 필요에 따라 상태를 복원하는 패턴
  • 옵저버: 객체의 상태 변화를 관찰하는 관찰자를 객체에 등록해 상태가 변할 때마다 객체가 관찰자에게 통지
  • 스테이트: 상태에 따라 객체가 행동을 변경하게 하는 패턴
  • 스트래티지: 행동을 클래스로 캡슐화해서 동적으로 행동을 바꿀 수 있게 하는 패턴
  • 템플릿 메서드: 일정 작업을 처리하는 부분을 서브클래스로 캡슐화해서 전체 수행 구조는 바꾸지 않으면서 특정 단계만 변경해서 수행하는 패턴
  • 비지터(visitor): 실제 로직을 가지고 있는 객체(비지터)가 로직을 적용할 객체를 방문해서 실행하는 패턴

 

2-5. REST API

https://www.ibm.com/kr-ko/topics/rest-apis

: 클라이언트가 서버에 데이터를 요청하고 접근할 수 있는 인터페이스로 REST 아키텍처를 준수한 API.

(REST: 주고 받는 Resource를 URI에 명시하여 HTTP 메서드(GET, POST, PUT, DELETE)를 통해 주고받는 것)

 

특징

1. 유니폼 인터페이스: 일관된 인터페이스로 언어, 플랫폼 등에 독립적이게 사용할 수 있다.

2. 무상태성(stateless): 서버에 상태 정보를 따로 쿠키나 세션에 저장하지 않는다. - 자유도가 높고 설계가 단순

3. 캐시 가능성: 클라이언트의 캐시에 저장해두고 같은 요청에서 해당 데이터를 사용하여 성능 개선

4. 레이어 시스템: 네트워크 상 여러 계층으로 구성될 수 있다. (클라이언트는 엔드포인트만 알면 통신 가능)

5. 클라이언트-서버 아키텍처

 

URI 설계 규칙

1. 마지막에는 '/'를 포함하지 않는다.

2. 언더바(_) 대신 하이픈(-)을 사용한다.

3. 행위(동사)가 아닌 결과(명사)를 포함한다. -> product (O), delete-product (X)

4. 소문자로 작성한다.

5. 파일의 확장자는 포함하지 않고, Accept 헤더를 사용한다.

반응형