스프링 부트 웹 애플리케이션 만들기
스프링 부트란 무엇인가?
스프링 포트폴리오를 미리 정의된 방식으로 신속하고 이식성이 있게
실제 서비스 환경에 사용할 수 있도록 조립해놓은 것
스프링 부트 특징
- 단독 실행 가능한 Spring 애플리케이션 생성
- Tomcat과 Jetty, Undertow를 직접 내장하여 WAR 파일을 배포할 필요 없음
- 빌드 구성을 단순화하기 위해 독자적인 '스타터' 의존성을 제공
- 가능한 Spring 및 3rd party 라이브러리에 대해 자동으로 설정되어 있음(CoC 적용)
- 메트릭, 상태 확인 및 외부 구성과 같은 상용화에 필요한 기능을 제공
- 설정을 위한 XML 코드를 생성하거나 요구하지 않음
리액티브 프로그래밍 소개
- 데이터 스트림 및 변경 전파: 데이터가 변경될 때마다 이벤트를 발생시켜서 데이터를 계속적으로 전달
- 선언적 프로그래밍: 실행할 동작을 구체적으로 명시하는 명령형 프로그래밍과 달리 선언형 프로그래밍은 단순히 목표를 선언
리액티브?
- 이벤트에 반응해서 동작
- 버튼을 누르면 기능이 동작하는 것처럼 main()으로 시작해서 정해진 작업을 수행하고 종료하는 방식을 제외한 요즘 모든 앱은 리액티브
- 리액티브 프로그래밍은 어디에나 있는 아주 흔한 것
리액티브의 개념이 적용된 예
- Push 방식: 데이터의 변화가 발생했을 때 변경이 발생한 곳에서 데이터를 보내주는 방식
- RTC(Real Time Communication)
- 소켓 프로그래밍
- DB Trigger
- Spring의 ApplicationEvent
- Angular의 데이터 바인딩
- 스마트폰의 Push 메시지
- Pull 방식: 변경된 데이터가 있는지 요청을 보내 질의하고 변경된 데이터를 가져오는 방식
- 클라이언트 요청 & 서버 응답 방식의 애플리케이션
- Java와 같은 절차형 프로그래밍 언어
프로젝트 리액터(Project Reactor)
VM웨어에서 만든 JVM에서 논블로킹 애플리케이션을 구축하기 위한 Reactive Streams 사양을 기반으로 하는 4세대 Reactive 라이브러리
- 프로젝트 리액터 특징
- 논블로킹, 비동기 프로그래밍 모델
- 함수형 프로그램이 스타일
- 스레드를 신경 쓸 필요 없는 동시성
Reactive Streams
- 논블로킹과 백 프레셔를 이용한 비동기 데이터 스트림 처리 표준
- JKD9 Flow API로 채택
- AkkaStreams, MongoDB, RxJava, Slick, ES, Kafka, Project Reactor
- 비동기 논블록킹 + 데이터 스트리밍 + 백 프레셔
- 표준 스펙 (JVM)으로 구현 기술 간의 상호 전환 가능
리액터 타입
- 프로젝트 리액터는 핵심 타입인
Flux <T>를사용해서 수요 조절 구현 Flux <T>- 데이터를 전달해주는 역할을 하는 플레이스 홀더(ex. 서빙 점원)
- 데이터 완성에 대한 반응 행동 처리(react)
- 논블로킹 방식으로 동작하기 때문에, 서버 스레드가 대기하지 않음
Future와 비슷하지만Future는 이미 시작되었음을 나타내는 반면Flux는 시작할 수 있음을 나태냄
- Publisher(ex. Kitchen)
- Subscriber(ex. Server)
- 메서드
- doOnNext: onNext로 데이터를 통지한 뒤 호출
- doOnError: onError 신호가 발생하면 호출
- doOnComplete: onComplete 신호가 발생하기 직전에 호출(플럭스 전용 연산자)
- doOnSubscribe: 구독을 시작하고 onSubscribe 신호가 발생하면 호출
- 구독(Subscription) 하기 전까지는 실제로 아무런 연산도 일어나지 않음
Mono: 0 또는 1개의 원소만 담을 수 있는 리액티브 발행자(Publisher)로 프로젝트 리액터에서 제공하는 구현체
스프링 웹 플럭스의 등장
- 스프링 포트폴리오에 스프링 프레임워크 5.0 버전 시점에 새로 편입된 구성 요소
- 스프링 MVC와 차이점
- 스프링 MVC는 자바 서블릿 API 기반으로 만들어짐
- 서블릿 3.1 이래로 비동기 방식을 일부 지원(불완전 리액티브)
- 리액티브 이벤트 루프와 배압 시그널 미지원
스프링 부트로 이커머스 플랫폼 만들기
실습 환경
- Java 8
- Spring Boot 2.4.2
- Template engine: Thymeleaf(https://www.thymeleaf.org/)
예제 코드
샘플 코드
Flux<Integer> seq = Flux.just(1, 2, 3); // Integer 값을 발생하는 Flux 생성
seq.subscribe(value -> System.out.println("데이터 : " + value)); // 구독
실행 결과
데이터 : 1
데이터 : 2
데이터 : 3
기타
스프링 리액티브를 쓰지 말아야 하는 이유
- 스프링 개발자가 아니라면
- 스프링 MVC로 개발해서 별문제 없이 잘 돌아간다면
- 블로킹 IO 작업이 있다면
- 블로킹이 뭔지는 모르겠으나 JPA, JDBC, MyBatis를 쓰고 있다면
- 리모트 서비스, API 호출이 전혀 없고, NoSQL도 사용하지 않고, 메세징 서비스 등을 사용하지 않는다면
- 개발팀이 크고 새롭고 도전적인 기술 학습과 시행착오에 대한 부담이 있다면
스프링 MVC 코드를 리액티브로 전환
- 컨트롤러의 리턴 타입을 T ->
Mono로 - 서비스 인터페이스 메서드의 리턴 타입도
Mono - 데이터를 직접 생성한다면
Mono.just() - 동기 함수 호출은
map으로 RestTemplate(동기/블로킹 API 호출) ->WebClient(비동기/논블로킹 API 호출)- 리액티브 지원 저장소는 MonoDB, Redis, Cassandra, Couchbase 호출
- 코드는
SpringData->Reactive버전으로 - 전달할 값이 없어도
then->Mono<Void>로 반드시 연결- 체인이 끊기면 실행되지 않음
- 체인이 시작된 후로 비동기 작업이 필요한 경우엔
flatMap()
- 예외 -> onErrorXX
- Controller에서 던지는
Flux <Order>와Mono <List <Order>>는 클라이언트 입장에서는 결과가 같음
참고
- "스프링 부트 실전 활용 마스터", 그렉 턴키스트 저(원서: "Hacking with Spring Boot 2.3 - Reactive Edition")
- https://spring.io/projects/spring-boot
- https://java.ihoney.pe.kr/372
- https://hyungjoon6876.github.io/jlog/2018/07/24/spring-reactor.html
- https://devsh.tistory.com/entry/프로젝트-리액터-고급-활용
- https://zetawiki.com/wiki/%EC%84%A4%EC%A0%95%EB%B3%B4%EB%8B%A4_%EA%B4%80%EC%8A%B5_CoC
- https://yunzai.dev/posts/RxJava_%EB%A6%AC%EC%97%91%ED%8B%B0%EB%B8%8C(Reative)_%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D%EC%9D%B4%EB%9E%80/
- https://techblog.woowahan.com/2619/
- https://www.baeldung.com/reactor-core
- https://tv.kakao.com/channel/3150758/cliplink/391418995
- https://wikidocs.net/141890
용어 정리
- CoC(Convention over Configuration): 설정보다 관습, 설정보다 관례, 설정보다 규약, 설정보다 컨벤션
'dev > Spring' 카테고리의 다른 글
| [정리] 스프링 부트 실전 활용 마스터(6) (0) | 2022.06.30 |
|---|---|
| [정리] 스프링 부트 실전 활용 마스터(5) (0) | 2022.06.23 |
| [정리] 스프링 부트 실전 활용 마스터(4) (0) | 2022.06.16 |
| [정리] 스프링 부트 실전 활용 마스터(3) (0) | 2022.05.26 |
| [정리] 스프링 부트 실전 활용 마스터(2) (0) | 2022.05.19 |