Spring WebFlux는 Spring 5부터 지원하는 리액티브 웹 애플리케이션을 위한 웹 프레임워크다.
Spring WebFlux는 Spring MVC 방식의 @Controller
, @RestController
, @RequestMapping
등과 같은 애너테이션을 동일하게 지원한다.
Spring WebFlux는 1차로 요청을 수신한 애플리케이션에서 외부 애플리케이션에 요청을 추가적으로 전달할 때 1차로 요청을 수신한 애플리케이션의 요청 처리 쓰레드가 Blocking 되지 않는다.
WebFlux
- Reactor의 타입인 Flux가 Web에서 사용되는 것
Reactive Stack | Servlet Stack |
---|---|
Netty, Servlet 3.1+ Containers | Servlet Containers |
Reactive Streams Adapters | Servlet API |
Spring Security Reactive | Spring Security |
Spring WebFlux | Spring MVC |
Spring Data Reactive Repositories - Mongo, Cassandra, Redis, Couchbase, R2DBC | Spring Data Repositories - JDBC, JPA,NoSQL |
Non-Blocking
유연함
Spring Security
웹 스택
Spring WebFlux의 경우 완전한 Non-Blocking 통신을 위해 리액티브 스택을 데이터 액세스 계층까지 확장한다.
R2DBC(Reactive Relation Database Connectivity)
- 관계형 데이터베이스에 Non-Blocking 통신을 적용하기 위한 표준 사양(Specification)이다.
- MySQL, Oracle 등의 데이터베이스 벤더에서는 R2DBC 사양에 맞는 드라이버를 구현해서 공급한다.
Spring WebFlux에서는 모든 데이터가 Mono나 Flux로 래핑되어 전달된다.
R2DBC는 Spring Data JDBC나 Spring Data JPA 처럼 애너테이션이나 컬렉션 등을 이용한 연관 관계 매핑은 지원하지 않는다.
error()
Operator
then()
Operator
switchIfEmpty()
Operator
private Mono<Member> findVerifiedMember(long memberId) {
return memberRepository
.findById(memberId)
.switchIfEmpty(Mono.error(new BusinessLogicException(ExceptionCode.MEMBER_NOT_FOUND)));
// switchIfEmpty() Operator는 emit되는 데이터가 없다면 switchIfEmpty() Operator의 파라미터로 전달되는 Publisher가 대체 동작을 수행할 수 있게 해주는 Operator다.
}
zipWith()
Operator
zipWith()
를 호출하는 Mono와 zipWith()
의 파라미터로 주어지는 Mono에서 emit하는 두 개의 데이터를 Tuple2
객체로 결합한 후, Downstream에 전달하는 Operator@Transactional(readOnly = true)
public Mono<Page<Member>> findMembers(PageRequest pageRequest) {
return memberRepository.findAllBy(pageRequest)
.collectList() // List 객체로 변환
.zipWith(memberRepository.count())
.map(tuple -> new PageImpl<>(tuple.getT1(), pageRequest, tuple.getT2()));
}
Spring 리액티브 스택의 경우, H2 웹 콘솔을 정상적으로 지원하지 않는다.
Spring Data R2DBC는 Auto DDL 기능을 제공하지 않기 때문에 직접 SQL 스크립트 설정을 추가해야 한다.
R2DBC의 Reposiroty를 사용하기 위해서는 Configuration 클래스에 @EnableR2dbcRepositories
애너테이션을 추가해 주어야 한다.
Auditing 기능을 사용하기 위해서는 Configuration 클래스에 @EnableR2dbcAuditing
애너테이션을 추가해 주어야한다.
request body를 Mono 타입으로 전달 받을 경우, Blocking 요소가 포함되지 않도록 request body를 전달 받는 순간부터 Non-Blocking으로 동
작하도록 Operator 체인을 바로 연결해서 다음 처리를 시작할 수 있다.
Spring WebFlux 기반 클래스는 Mono와 같이 Mono로 래핑한 값을 리턴한다.
Spring WebFlux에서는 모든 데이터가 Mono나 Flux로 래핑되어 전달된다.
CoffeeController의 postCoffee() 핸들러 메서드에 Spring WebFlux를 적용
CoffeeService의 createCoffee() 메서드에 Spring WebFlux를 적용
데이터베이스에 커피 정보를 등록
R2dbcEntityTemplate
을 사용해서 커피 정보를 데이터베이스에 등록