Spring Boot 2 WebFlux Restful 基于annotation实现 教程(二)

一、简介

Spring WebFlux

Spring 官方文档对 Spring WebFlux 介绍如下:

FROM https://docs.spring.io/spring-framework/docs/5.0.0.BUILD-SNAPSHOT/spring-framework-reference/html/web-reactive.html

Spring Framework 5 includes a new spring-webflux module. The module contains support for reactive HTTP and WebSocket clients as well as for reactive server web applications including REST, HTML browser, and WebSocket style interactions.

Spring Framework 5 提供了一个新的 spring-webflux 模块。该模块包含了:

  • 对响应式支持的 HTTP 和 WebSocket 客户端。
  • 对响应式支持的 Web 服务器,包括 Rest API、HTML 浏览器、WebSocket 等交互方式。

On the server-side WebFlux supports 2 distinct programming models:

  • Annotation-based with @Controller and the other > annotations supported also with Spring MVC
  • Functional, Java 8 lambda style routing and handling

下图显示了服务端的技术栈,左侧是 spring-webmvc 模块中传统的、基于 Servlet 的 Spring MVC ,右侧是 spring-webflux 模块中的响应式技术栈。

webflux-overview

  • 仔细看第一层的两个框框,分别是上面提到的 WebFlux 的两种编程模型。表达的是 SpringMVC 不支持 Router Functions 方式,而 WebFlux 支持。

WebFlux can run on Servlet containers with support for the Servlet 3.1 Non-Blocking IO API as well as on other async runtimes such as Netty and Undertow.

WebFlux 可以运行在:

  • 支持 Servlet 3.1 非阻塞 IO API 的 Servlet 容器上
  • 也可以运行在支持异步运行时的,例如说 Netty 或者 Undertow 上

Each runtime is adapted to a reactive ServerHttpRequest and ServerHttpResponse exposing the body of the request and response as Flux, rather than InputStream and OutputStream, with reactive backpressure.

每一个运行时(runtime)适用于将响应式的 ServerHttpRequest 和 ServerHttpResponse 中 request 和 response 的 body 暴露成 Flux<DataBuffer> 对象,而不是 InputStream 和 InputStream 对象,可用于响应式中的背压(backpressure)。这段有点晦涩,简单来说:

REST-style JSON and XML serialization and deserialization is supported on top as a Flux<Object>, and so is HTML view rendering and Server-Sent Events.

REST 风格 API 使用到的 JSON 和 XML 序列化和反序列化,需要提供对 Flux<Object> 的支持。对于 HTML 渲染,和 SSE 也要提供对 Flux<Object> 的支持。

二、快速入门
  1、引入依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <artifactId>spring-boot-parent</artifactId>
        <groupId>org.springframework.boot</groupId>
        <version>2.3.1.RELEASE</version>
    </parent>
    <groupId>com.mscloudmesh</groupId>
    <artifactId>springboot-webflux</artifactId>
    <version>1.0-SNAPSHOT</version>

   <dependencies>

       <dependency>
           <groupId>org.projectlombok</groupId>
           <artifactId>lombok</artifactId>
       </dependency>
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-test</artifactId>
       </dependency>

       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-webflux</artifactId>
       </dependency>
   </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

2.实体类UserInfo

package com.mscloudmesh.webflux.annotation.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Data
@Slf4j
@AllArgsConstructor
@NoArgsConstructor
public class UserInfo implements java.io.Serializable {
    private Long id;

    private String userName;

    private Integer age;

}

3、数据交互层UserRepository(这里用一个map模拟数据库操作)

package com.mscloudmesh.webflux.annotation.repository;

import com.mscloudmesh.webflux.annotation.model.UserInfo;
import org.springframework.stereotype.Repository;

import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicLong;

@Repository
public class UserRepository {

    private ConcurrentMap<Long, UserInfo>
            userDataMap = new ConcurrentHashMap<Long, UserInfo>();

    private static final AtomicLong idGenerator = new AtomicLong(0);

    public UserInfo save(UserInfo userInfo) {
        Long id = idGenerator.incrementAndGet();
        UserInfo info = new UserInfo(id, "kevin", 30);
        userDataMap.put(id, userInfo);
        return userInfo;
    }

    public Collection<UserInfo> findAll() {
        return userDataMap.values();
    }


    public UserInfo findByUsrId(Long id) {
        return userDataMap.get(id);
    }

    public UserInfo updateUserInfo(UserInfo userInfo) {
        userDataMap.put(userInfo.getId(), userInfo);
        return userInfo;

    }

    public Long deleteUserById(Long id) {
        userDataMap.remove(id);
        return id;
    }

}

4.handler实现

package com.mscloudmesh.webflux.annotation.service;


import com.mscloudmesh.webflux.annotation.model.UserInfo;
import com.mscloudmesh.webflux.annotation.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

@Service
public class UserHandler {

    @Autowired
    private UserRepository repository;

    public Mono<UserInfo> save(UserInfo userInfo) {
        return Mono.create(userInfoMonoSink -> userInfoMonoSink.success(repository.save(userInfo)));
    }

    public Mono<UserInfo> findByUserId(Long id) {
        return Mono.justOrEmpty(repository.findByUsrId(id));
    }


    public Mono<UserInfo> updateUser(UserInfo userInfo) {
        return Mono.create(userInfoMonoSink -> userInfoMonoSink.success(repository.save(userInfo)));
    }

    public Mono<Long> deleteUserById(Long id) {
        return Mono.create(userInfoMongoSink -> userInfoMongoSink.success(repository.deleteUserById(id)));
    }

}

5.controller测试类

package com.mscloudmesh.webflux.annotation.controller;

import com.mscloudmesh.webflux.annotation.model.UserInfo;
import com.mscloudmesh.webflux.annotation.service.UserHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;

@RestController
@RequestMapping("/webflux")
public class UserWebfluxController {

    @Autowired
    private UserHandler userHandler;

    @RequestMapping("/save")
    public Mono<UserInfo> save(UserInfo info){
        return userHandler.save(info);
    }

    @RequestMapping("/findById")
    public Mono<UserInfo> findById(Long id ){

        return userHandler.findByUserId(id);
    }
}
开始测试一下:
   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值