[Spring] WebFlux

Self-Study/Spring / / 2022. 8. 24. 15:51

References

https://docs.spring.io/spring-framework/docs/current/reference/html/web-reactive.html

https://devuna.tistory.com/108

https://devuna.tistory.com/120

https://blog.clairvoyantsoft.com/reactive-crud-apis-with-spring-webflux-88509634daa

 

WebFlux의 정의

WebFluxSpring 5에서 새롭게 추가된 모듈이다.

클라이언트 - 서버 간 반응형 어플리케이션 개발을 도와주는 역할로, non-blocking반응형 stream을 지원한다.

장점 단점
다량의 데이터 처리에 최적화 오류처리가 복잡함
spring과 완벽한 호환성 Back Pressure 기능이 없음
netty 지원  
비동기 non-blocking 메시지 처리
 

netty : Java 네트워크 어플리케이션 프레임워크

non-blocking : A함수가 B함수를 호출해도 제어권을 A함수가 그대로 가지는 성질. 이로 인해 B함수의 실행 및 완료를 기다릴 필요가 없어진다.

Back Pressure : Push하는 데이터의 흐름을 제어하는 성질

 

WebFlux의 요소

Spring WebFlux에서 사용되는 반응형 라이브는 Reactor 객체로 MonoFlux로 나뉜다.

Mono

0 ~ 1개의 데이터를 처리한다.

Mono.fromCallable(System::currentTimeMillis)
    .flatMap(time -> Mono.first(serviceA.findRecent(time), serviceB.findRecent(time)))
    .timeout(Duration.ofSeconds(3), errorHandler::fallback)
    .doOnSuccess(r -> serviceM.incrementSuccess())
    .subscribe(System.out::println);

Flux

0 ~ N개의 데이터를 전달한다.

Flux.fromIterable(getSomeLongList())
    .mergeWith(Flux.interval(100))
    .doOnNext(serviceA::someObserver)
    .map(d -> d * 2)
    .take(3)
    .onErrorResume(errorHandler::fallback)
    .doAfterTerminate(serviceM::incrementTerminate)
    .subscribe(System.out::println);

 

WebFlux의 사용 예시

Controller

@RestController
@RequestMapping("/home")
public class SampleController {
    @Autowired
    private SampleService sampleService;
		
    // 여러개의 데이터를 가져올 땐, Flux를 사용한다
    @GetMapping("/")
    public Flux<Object> getSample() {
        // List 형태의 데이터 타입을 return 하는 함수를 호출할 때는, fromIterable()
        // 단일 데이터 타입을 return 하는 함수를 호출할 때는, just()를 사용한다
        return Flux.fromIterable(sampleService.getSample());
    }
		
    // 사용자 정의 객체를 보낼 때 단일로 보낸다면 Mono를 사용한다!
    @PostMapping("/")
    public Mono postSample(@Requestbody SampleVO sampleVO) {
        return sampleService.postSample(sampleVO);
    }

    @PutMapping("/")
    public Mono putSample(String id, String content) {
        return sampleService.putSample(id, content);
    }

    @DeleteMapping("/")
    public Mono deleteSample(String id) {
        return sampleService.deleteSample(id);
    }
}

Service

@Service
public class SampleService {
    @Autowired
    private SampleMapper sampleMapper;

    public List<SampleVO> getSample() {
        return sampleMapper.getSample();
    }

    public Mono postSample(SampleVO sampleVO) {
        return sampleMapper.postSample(sampleVO);
    }

    public Mono putSample(String id, String content) {
        return sampleMapper.putSample(id, content);
    }

    public Mono deleteSample(String id) {
        return sampleMapper.deleteSample(id);
    }
}

Mapper

@Mapper
public interface SampleMapper {
    List<SampleVO> getSample();

    Mono postSample(SampleVO sampleVO);

    Mono putSample(String id, String content);

    Mono deleteSample(String id);
}

 

Spring MVC vs WebFlux

기존 Spring MVCSpring WebFlux 둘을 비교했을 때 대표적인 사항은 다음과 같다.

  • 간단한 구현 및 디버깅, JDBC 및 JPA에 의존 ⇒ Spring MVC
  • 대규모 데이터 처리 및 경량으로 Spring 프레임워크 이용 ⇒ Spring WebFlux