引入

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.2.4</version>
</parent>
​
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-webflux</artifactId>
    </dependency>
</dependencies>

组件对比

ServletWebFlux组件对比


Controller

package com.tlovo.webflux.controller;
​
import org.springframework.http.MediaType;
import org.springframework.http.codec.ServerSentEvent;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
​
import java.time.Duration;
​
@RestController
public class HelloController {
​
    @GetMapping("/hello")
    public Mono<String> hello() {
        return Mono.just("Hello!");
    }
​
    @GetMapping("/hellos")
    public Flux<String> hellos() {
        return Flux.just("h1", "h2", "h3");
    }
​
    /**
     * Server Sent Event => 服务端推送事件
     */
    @GetMapping(value = "/sse", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<ServerSentEvent<String>> sse() {
        return Flux.range(1, 10)
                .map(i -> {
                    // 构建一个SSE对象
                    return ServerSentEvent.builder("h-" + i)
                            .id(i + "")
                            .comment("hei-" + i)
                            .event("haha")
                            .build();
                })
                .delayElements(Duration.ofMillis(500));
    }
}

自定义配置

WebFluxConfigurer

例如配置跨域:

package com.tlovo.webflux.config;
​
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.lang.NonNull;
import org.springframework.web.reactive.config.CorsRegistry;
import org.springframework.web.reactive.config.WebFluxConfigurer;
​
@Configuration
public class MyWebConfiguration {
    @Bean
    public WebFluxConfigurer webFluxConfigurer() {
        return new WebFluxConfigurer() {
            @Override
            public void addCorsMappings(@NonNull CorsRegistry registry) {
                registry.addMapping("/**")
                        .allowedHeaders("*")
                        .allowedMethods("*")
                        .allowedOrigins("localhost");
            }
        };
    }
}

Filter

package com.tlovo.webflux.filter;
​
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;
​
@Component
public class MyWebFilter implements WebFilter {
​
    @NonNull
    @Override
    public Mono<Void> filter(@NonNull ServerWebExchange exchange, WebFilterChain chain) {
        System.out.println("请求处理放行到目标方法之前...");
        // 流一旦经过某个操作后就会变成新流
        Mono<Void> filter = chain
            .filter(exchange) // 放行
            .doOnError(ex -> {
                System.out.println("目标方法异常以后...");
            }) // 目标方法发生异常后
            .doFinally(s -> {
                System.out.println("目标方法执行以后...");
            }); // 目标方法执行之后
​
        return filter;
    }
}

规则,就是用来打破的( ̄へ ̄)!