springboot webflux 简介


springboot webflux 简介

 

官网:https://docs.spring.io/spring-boot/docs/2.3.0.RELEASE/reference/html/spring-boot-features.html#boot-features-webflux

 

**********************

简介

 

                      

基于reactor实现的异步非阻塞框架,较同步阻塞的MVC框架,可提升系统性能;

可使用MVC的注解操作,也可使用函数式编程;

支持传统的servlet容器,还可运行在支持nio的netty、undertow容器中

 

 

**********************

相关类与接口

 

ServerWebExchange:获取request、response、session

public interface ServerWebExchange {
    String LOG_ID_ATTRIBUTE = ServerWebExchange.class.getName() + ".LOG_ID";

    ServerHttpRequest getRequest();        //获取request
    ServerHttpResponse getResponse();      //获取response
    Map<String, Object> getAttributes();   //获取请求中的属性

    @Nullable
    default <T> T getAttribute(String name) {
        return this.getAttributes().get(name);
    }

    default <T> T getRequiredAttribute(String name) {
        T value = this.getAttribute(name);
        Assert.notNull(value, () -> {
            return "Required attribute '" + name + "' is missing";
        });
        return value;
    }

    default <T> T getAttributeOrDefault(String name, T defaultValue) {
        return this.getAttributes().getOrDefault(name, defaultValue);
    }

    Mono<WebSession> getSession();                 //获取webSession
    <T extends Principal> Mono<T> getPrincipal();  //获取认证用户

    Mono<MultiValueMap<String, String>> getFormData();      //获取表单参数
    Mono<MultiValueMap<String, Part>> getMultipartData();   //获取表单multipart数据

    LocaleContext getLocaleContext();              //获取国际化设置(Locale)

    @Nullable
    ApplicationContext getApplicationContext();    //获取应用上下文

    boolean isNotModified();
    boolean checkNotModified(Instant var1);
    boolean checkNotModified(String var1);
    boolean checkNotModified(@Nullable String var1, Instant var2);

    String transformUrl(String var1);
    void addUrlTransformer(Function<String, String> var1);

    String getLogPrefix();

    default ServerWebExchange.Builder mutate() {
        return new DefaultServerWebExchangeBuilder(this);
    }

    public interface Builder {           //构造ServeraWebExchange
        ServerWebExchange.Builder request(Consumer<org.springframework.http.server.reactive.ServerHttpRequest.Builder> var1);

        ServerWebExchange.Builder request(ServerHttpRequest var1);       //设置请求
        ServerWebExchange.Builder response(ServerHttpResponse var1);     //设置响应

        ServerWebExchange.Builder principal(Mono<Principal> var1);       //设置认证用户
        ServerWebExchange build();                                       //返回ServerWebExchange
    }
}

 

 

**********************

ServerHttpRequest

 

ServerHttpRequest

public interface ServerHttpRequest extends HttpRequest, ReactiveHttpInputMessage {
    String getId();

    RequestPath getPath();
    MultiValueMap<String, String> getQueryParams();
    MultiValueMap<String, HttpCookie> getCookies();

    @Nullable
    default InetSocketAddress getLocalAddress() {
        return null;
    }

    @Nullable
    default InetSocketAddress getRemoteAddress() {
        return null;
    }

    @Nullable
    default SslInfo getSslInfo() {
        return null;
    }

    default ServerHttpRequest.Builder mutate() {
        return new DefaultServerHttpRequestBuilder(this);
    }

    public interface Builder {
        ServerHttpRequest.Builder method(HttpMethod var1);
        ServerHttpRequest.Builder uri(URI var1);
        ServerHttpRequest.Builder path(String var1);
        ServerHttpRequest.Builder contextPath(String var1);

        ServerHttpRequest.Builder header(String var1, String... var2);
        ServerHttpRequest.Builder headers(Consumer<HttpHeaders> var1);

        ServerHttpRequest.Builder sslInfo(SslInfo var1);
        ServerHttpRequest build();
    }
}

 

HttpRequest

public interface HttpRequest extends HttpMessage {
    @Nullable
    default HttpMethod getMethod() {
        return HttpMethod.resolve(this.getMethodValue());  //将请求方法转换为HttpMethod
    }

    String getMethodValue();        //获取请求方法
    URI getURI();                   //获取请求uri
}

 

HttpMessage

public interface HttpMessage {
    HttpHeaders getHeaders();   //获取请求头
}

 

ReactiveHttpInputMessage

public interface ReactiveHttpInputMessage extends HttpMessage {
    Flux<DataBuffer> getBody();
}

 

 

**********************

ServerHttpResponse

 

ServerHttpResponse

public interface ServerHttpResponse extends ReactiveHttpOutputMessage {
    boolean setStatusCode(@Nullable HttpStatus var1);

    @Nullable
    HttpStatus getStatusCode();

    default boolean setRawStatusCode(@Nullable Integer value) {
        if (value == null) {
            return this.setStatusCode((HttpStatus)null);
        } else {
            HttpStatus httpStatus = HttpStatus.resolve(value);
            if (httpStatus == null) {
                throw new IllegalStateException("Unresolvable HttpStatus for general ServerHttpResponse: " + value);
            } else {
                return this.setStatusCode(httpStatus);
            }
        }
    }

    @Nullable
    default Integer getRawStatusCode() {
        HttpStatus httpStatus = this.getStatusCode();
        return httpStatus != null ? httpStatus.value() : null;
    }

    MultiValueMap<String, ResponseCookie> getCookies();
    void addCookie(ResponseCookie var1);
}

 

ReactiveHttpOutputMessage

public interface ReactiveHttpOutputMessage extends HttpMessage {
    DataBufferFactory bufferFactory();

    void beforeCommit(Supplier<? extends Mono<Void>> var1);
    boolean isCommitted();

    Mono<Void> writeWith(Publisher<? extends DataBuffer> var1);
    Mono<Void> writeAndFlushWith(Publisher<? extends Publisher<? extends DataBuffer>> var1);

    Mono<Void> setComplete();
}

 

 

**********************

WebSession

 

webSession:存储应用session数据

public interface WebSession {
    String getId();

    Map<String, Object> getAttributes();

    @Nullable
    default <T> T getAttribute(String name) {
        return this.getAttributes().get(name);
    }

    default <T> T getRequiredAttribute(String name) {
        T value = this.getAttribute(name);
        Assert.notNull(value, () -> {
            return "Required attribute '" + name + "' is missing.";
        });
        return value;
    }

    default <T> T getAttributeOrDefault(String name, T defaultValue) {
        return this.getAttributes().getOrDefault(name, defaultValue);
    }

    void start();
    boolean isStarted();

    Mono<Void> changeSessionId();

    Mono<Void> invalidate();
    Mono<Void> save();

    boolean isExpired();
    Instant getCreationTime();
    Instant getLastAccessTime();

    void setMaxIdleTime(Duration var1);
    Duration getMaxIdleTime();
}

 

 

**********************

context信息

 

LocaleContext:国际化上下文

public interface LocaleContext {
    @Nullable
    Locale getLocale();
}

 

ApplicationContext:应用上下文

public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
    @Nullable
    String getId();
    String getApplicationName();

    String getDisplayName();
    long getStartupDate();

    @Nullable
    ApplicationContext getParent();
    AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;
}

 

 

**********************

函数式类与接口

 

**********************

RouterFunction

 

RouterFunction

@FunctionalInterface
public interface RouterFunction<T extends ServerResponse> {
    Mono<HandlerFunction<T>> route(ServerRequest var1);

    default RouterFunction<T> and(RouterFunction<T> other) {
        return new SameComposedRouterFunction(this, other);
    }

    default RouterFunction<?> andOther(RouterFunction<?> other) {
        return new DifferentComposedRouterFunction(this, other);
    }

    default RouterFunction<T> andRoute(RequestPredicate predicate, HandlerFunction<T> handlerFunction) {
        return this.and(RouterFunctions.route(predicate, handlerFunction));
    }

    default RouterFunction<T> andNest(RequestPredicate predicate, RouterFunction<T> routerFunction) {
        return this.and(RouterFunctions.nest(predicate, routerFunction));
    }

    default <S extends ServerResponse> RouterFunction<S> filter(HandlerFilterFunction<T, S> filterFunction) {
        return new FilteredRouterFunction(this, filterFunction);
    }

    default void accept(Visitor visitor) {
        visitor.unknown(this);
    }
}

 

RouterFunctionBuilder:构造RouterFunction

class RouterFunctionBuilder implements Builder {
    private List<RouterFunction<ServerResponse>> routerFunctions = new ArrayList();
    private List<HandlerFilterFunction<ServerResponse, ServerResponse>> filterFunctions = new ArrayList();

    RouterFunctionBuilder() {
    }

    public Builder add(RouterFunction<ServerResponse> routerFunction) {
        Assert.notNull(routerFunction, "RouterFunction must not be null");
        this.routerFunctions.add(routerFunction);
        return this;
    }

    private Builder add(RequestPredicate predicate, HandlerFunction<ServerResponse> handlerFunction) {
        this.routerFunctions.add(RouterFunctions.route(predicate, handlerFunction));
        return this;
    }

    public Builder GET(String pattern, HandlerFunction<ServerResponse> handlerFunction) {
        return this.add(RequestPredicates.GET(pattern), handlerFunction);
    }

    public Builder GET(String pattern, RequestPredicate predicate, HandlerFunction<ServerResponse> handlerFunction) {
        return this.add(RequestPredicates.GET(pattern).and(predicate), handlerFunction);
    }

    public Builder HEAD(String pattern, HandlerFunction<ServerResponse> handlerFunction) {
        return this.add(RequestPredicates.HEAD(pattern), handlerFunction);
    }

    public Builder HEAD(String pattern, RequestPredicate predicate, HandlerFunction<ServerResponse> handlerFunction) {
        return this.add(RequestPredicates.HEAD(pattern).and(predicate), handlerFunction);
    }

    public Builder POST(String pattern, HandlerFunction<ServerResponse> handlerFunction) {
        return this.add(RequestPredicates.POST(pattern), handlerFunction);
    }

    public Builder POST(String pattern, RequestPredicate predicate, HandlerFunction<ServerResponse> handlerFunction) {
        return this.add(RequestPredicates.POST(pattern).and(predicate), handlerFunction);
    }

    public Builder PUT(String pattern, HandlerFunction<ServerResponse> handlerFunction) {
        return this.add(RequestPredicates.PUT(pattern), handlerFunction);
    }

    public Builder PUT(String pattern, RequestPredicate predicate, HandlerFunction<ServerResponse> handlerFunction) {
        return this.add(RequestPredicates.PUT(pattern).and(predicate), handlerFunction);
    }

    public Builder PATCH(String pattern, HandlerFunction<ServerResponse> handlerFunction) {
        return this.add(RequestPredicates.PATCH(pattern), handlerFunction);
    }

    public Builder PATCH(String pattern, RequestPredicate predicate, HandlerFunction<ServerResponse> handlerFunction) {
        return this.add(RequestPredicates.PATCH(pattern).and(predicate), handlerFunction);
    }

    public Builder DELETE(String pattern, HandlerFunction<ServerResponse> handlerFunction) {
        return this.add(RequestPredicates.DELETE(pattern), handlerFunction);
    }

    public Builder DELETE(String pattern, RequestPredicate predicate, HandlerFunction<ServerResponse> handlerFunction) {
        return this.add(RequestPredicates.DELETE(pattern).and(predicate), handlerFunction);
    }

    public Builder OPTIONS(String pattern, HandlerFunction<ServerResponse> handlerFunction) {
        return this.add(RequestPredicates.OPTIONS(pattern), handlerFunction);
    }

    public Builder OPTIONS(String pattern, RequestPredicate predicate, HandlerFunction<ServerResponse> handlerFunction) {
        return this.add(RequestPredicates.OPTIONS(pattern).and(predicate), handlerFunction);
    }

    public Builder route(RequestPredicate predicate, HandlerFunction<ServerResponse> handlerFunction) {
        return this.add(RouterFunctions.route(predicate, handlerFunction));
    }

    public Builder resources(String pattern, Resource location) {
        return this.add(RouterFunctions.resources(pattern, location));
    }

    public Builder resources(Function<ServerRequest, Mono<Resource>> lookupFunction) {
        return this.add(RouterFunctions.resources(lookupFunction));
    }

    public Builder nest(RequestPredicate predicate, Consumer<Builder> builderConsumer) {
        Assert.notNull(builderConsumer, "Consumer must not be null");
        RouterFunctionBuilder nestedBuilder = new RouterFunctionBuilder();
        builderConsumer.accept(nestedBuilder);
        RouterFunction<ServerResponse> nestedRoute = nestedBuilder.build();
        this.routerFunctions.add(RouterFunctions.nest(predicate, nestedRoute));
        return this;
    }

    public Builder nest(RequestPredicate predicate, Supplier<RouterFunction<ServerResponse>> routerFunctionSupplier) {
        Assert.notNull(routerFunctionSupplier, "RouterFunction Supplier must not be null");
        RouterFunction<ServerResponse> nestedRoute = (RouterFunction)routerFunctionSupplier.get();
        this.routerFunctions.add(RouterFunctions.nest(predicate, nestedRoute));
        return this;
    }

    public Builder path(String pattern, Consumer<Builder> builderConsumer) {
        return this.nest(RequestPredicates.path(pattern), builderConsumer);
    }

    public Builder path(String pattern, Supplier<RouterFunction<ServerResponse>> routerFunctionSupplier) {
        return this.nest(RequestPredicates.path(pattern), routerFunctionSupplier);
    }

    public Builder filter(HandlerFilterFunction<ServerResponse, ServerResponse> filterFunction) {
        Assert.notNull(filterFunction, "HandlerFilterFunction must not be null");
        this.filterFunctions.add(filterFunction);
        return this;
    }

    public Builder before(Function<ServerRequest, ServerRequest> requestProcessor) {
        Assert.notNull(requestProcessor, "RequestProcessor must not be null");
        return this.filter((request, next) -> {
            return next.handle((ServerRequest)requestProcessor.apply(request));
        });
    }

    public Builder after(BiFunction<ServerRequest, ServerResponse, ServerResponse> responseProcessor) {
        Assert.notNull(responseProcessor, "ResponseProcessor must not be null");
        return this.filter((request, next) -> {
            return next.handle(request).map((serverResponse) -> {
                return (ServerResponse)responseProcessor.apply(request, serverResponse);
            });
        });
    }

    public Builder onError(Predicate<? super Throwable> predicate, BiFunction<? super Throwable, ServerRequest, Mono<ServerResponse>> responseProvider) {
        Assert.notNull(predicate, "Predicate must not be null");
        Assert.notNull(responseProvider, "ResponseProvider must not be null");
        return this.filter((request, next) -> {
            return next.handle(request).onErrorResume(predicate, (t) -> {
                return (Mono)responseProvider.apply(t, request);
            });
        });
    }

    public <T extends Throwable> Builder onError(Class<T> exceptionType, BiFunction<? super T, ServerRequest, Mono<ServerResponse>> responseProvider) {
        Assert.notNull(exceptionType, "ExceptionType must not be null");
        Assert.notNull(responseProvider, "ResponseProvider must not be null");
        return this.filter((request, next) -> {
            return next.handle(request).onErrorResume(exceptionType, (t) -> {
                return (Mono)responseProvider.apply(t, request);
            });
        });
    }

    public RouterFunction<ServerResponse> build() {
        if (this.routerFunctions.isEmpty()) {
            throw new IllegalStateException("No routes registered. Register a route with GET(), POST(), etc.");
        } else {
            RouterFunction<ServerResponse> result = new RouterFunctionBuilder.BuiltRouterFunction(this.routerFunctions);
            if (this.filterFunctions.isEmpty()) {
                return result;
            } else {
                HandlerFilterFunction<ServerResponse, ServerResponse> filter = (HandlerFilterFunction)this.filterFunctions.stream().reduce(HandlerFilterFunction::andThen).orElseThrow(IllegalStateException::new);
                return result.filter(filter);
            }
        }
    }

    private static class BuiltRouterFunction extends AbstractRouterFunction<ServerResponse> {
        private List<RouterFunction<ServerResponse>> routerFunctions;

        public BuiltRouterFunction(List<RouterFunction<ServerResponse>> routerFunctions) {
            Assert.notEmpty(routerFunctions, "RouterFunctions must not be empty");
            this.routerFunctions = routerFunctions;
        }

        public Mono<HandlerFunction<ServerResponse>> route(ServerRequest request) {
            return Flux.fromIterable(this.routerFunctions).concatMap((routerFunction) -> {
                return routerFunction.route(request);
            }).next();
        }

        public void accept(Visitor visitor) {
            this.routerFunctions.forEach((routerFunction) -> {
                routerFunction.accept(visitor);
            });
        }
    }
}

 

RouterFunctions:构造RouterFunction

public abstract class RouterFunctions {
    private static final Log logger = LogFactory.getLog(RouterFunctions.class);
    public static final String REQUEST_ATTRIBUTE = RouterFunctions.class.getName() + ".request";
    public static final String URI_TEMPLATE_VARIABLES_ATTRIBUTE = RouterFunctions.class.getName() + ".uriTemplateVariables";
    public static final String MATCHING_PATTERN_ATTRIBUTE = RouterFunctions.class.getName() + ".matchingPattern";

    public RouterFunctions() {
    }

    public static RouterFunctions.Builder route() {
        return new RouterFunctionBuilder();
    }

    public static <T extends ServerResponse> RouterFunction<T> route(RequestPredicate predicate, HandlerFunction<T> handlerFunction) {
        return new RouterFunctions.DefaultRouterFunction(predicate, handlerFunction);
    }

    public static <T extends ServerResponse> RouterFunction<T> nest(RequestPredicate predicate, RouterFunction<T> routerFunction) {
        return new RouterFunctions.DefaultNestedRouterFunction(predicate, routerFunction);
    }

    public static RouterFunction<ServerResponse> resources(String pattern, Resource location) {
        return resources(resourceLookupFunction(pattern, location));
    }

    public static Function<ServerRequest, Mono<Resource>> resourceLookupFunction(String pattern, Resource location) {
        return new PathResourceLookupFunction(pattern, location);
    }

    public static RouterFunction<ServerResponse> resources(Function<ServerRequest, Mono<Resource>> lookupFunction) {
        return new RouterFunctions.ResourcesRouterFunction(lookupFunction);
    }

    public static HttpHandler toHttpHandler(RouterFunction<?> routerFunction) {
        return toHttpHandler(routerFunction, HandlerStrategies.withDefaults());
    }

    public static HttpHandler toHttpHandler(RouterFunction<?> routerFunction, HandlerStrategies strategies) {
        WebHandler webHandler = toWebHandler(routerFunction, strategies);
        return WebHttpHandlerBuilder.webHandler(webHandler).filters((filters) -> {
            filters.addAll(strategies.webFilters());
        }).exceptionHandlers((handlers) -> {
            handlers.addAll(strategies.exceptionHandlers());
        }).localeContextResolver(strategies.localeContextResolver()).build();
    }

    public static WebHandler toWebHandler(RouterFunction<?> routerFunction) {
        return toWebHandler(routerFunction, HandlerStrategies.withDefaults());
    }

    public static WebHandler toWebHandler(RouterFunction<?> routerFunction, HandlerStrategies strategies) {
        Assert.notNull(routerFunction, "RouterFunction must not be null");
        Assert.notNull(strategies, "HandlerStrategies must not be null");
        return new RouterFunctions.RouterFunctionWebHandler(strategies, routerFunction);
    }

    private static class RouterFunctionWebHandler implements WebHandler {
        private static final HandlerFunction<ServerResponse> NOT_FOUND_HANDLER = (request) -> {
            return ServerResponse.notFound().build();
        };
        private final HandlerStrategies strategies;
        private final RouterFunction<?> routerFunction;

        public RouterFunctionWebHandler(HandlerStrategies strategies, RouterFunction<?> routerFunction) {
            this.strategies = strategies;
            this.routerFunction = routerFunction;
        }

        public Mono<Void> handle(ServerWebExchange exchange) {
            return Mono.defer(() -> {
                ServerRequest request = new DefaultServerRequest(exchange, this.strategies.messageReaders());
                this.addAttributes(exchange, request);
                return this.routerFunction.route(request).defaultIfEmpty(notFound()).flatMap((handlerFunction) -> {
                    return wrapException(() -> {
                        return handlerFunction.handle(request);
                    });
                }).flatMap((response) -> {
                    return wrapException(() -> {
                        return response.writeTo(exchange, new RouterFunctions.HandlerStrategiesResponseContext(this.strategies));
                    });
                });
            });
        }

        private void addAttributes(ServerWebExchange exchange, ServerRequest request) {
            Map<String, Object> attributes = exchange.getAttributes();
            attributes.put(RouterFunctions.REQUEST_ATTRIBUTE, request);
        }

        private static <T extends ServerResponse> HandlerFunction<T> notFound() {
            return NOT_FOUND_HANDLER;
        }

        private static <T> Mono<T> wrapException(Supplier<Mono<T>> supplier) {
            try {
                return (Mono)supplier.get();
            } catch (Throwable var2) {
                return Mono.error(var2);
            }
        }
    }

    private static class HandlerStrategiesResponseContext implements Context {
        private final HandlerStrategies strategies;

        public HandlerStrategiesResponseContext(HandlerStrategies strategies) {
            this.strategies = strategies;
        }

        public List<HttpMessageWriter<?>> messageWriters() {
            return this.strategies.messageWriters();
        }

        public List<ViewResolver> viewResolvers() {
            return this.strategies.viewResolvers();
        }
    }

    private static class ResourcesRouterFunction extends RouterFunctions.AbstractRouterFunction<ServerResponse> {
        private final Function<ServerRequest, Mono<Resource>> lookupFunction;

        public ResourcesRouterFunction(Function<ServerRequest, Mono<Resource>> lookupFunction) {
            Assert.notNull(lookupFunction, "Function must not be null");
            this.lookupFunction = lookupFunction;
        }

        public Mono<HandlerFunction<ServerResponse>> route(ServerRequest request) {
            return ((Mono)this.lookupFunction.apply(request)).map(ResourceHandlerFunction::new);
        }

        public void accept(RouterFunctions.Visitor visitor) {
            visitor.resources(this.lookupFunction);
        }
    }

    private static final class DefaultNestedRouterFunction<T extends ServerResponse> extends RouterFunctions.AbstractRouterFunction<T> {
        private final RequestPredicate predicate;
        private final RouterFunction<T> routerFunction;

        public DefaultNestedRouterFunction(RequestPredicate predicate, RouterFunction<T> routerFunction) {
            Assert.notNull(predicate, "Predicate must not be null");
            Assert.notNull(routerFunction, "RouterFunction must not be null");
            this.predicate = predicate;
            this.routerFunction = routerFunction;
        }

        public Mono<HandlerFunction<T>> route(ServerRequest serverRequest) {
            return (Mono)this.predicate.nest(serverRequest).map((nestedRequest) -> {
                if (RouterFunctions.logger.isTraceEnabled()) {
                    String logPrefix = serverRequest.exchange().getLogPrefix();
                    RouterFunctions.logger.trace(logPrefix + String.format("Matched nested %s", this.predicate));
                }

                return this.routerFunction.route(nestedRequest).doOnNext((match) -> {
                    if (nestedRequest != serverRequest) {
                        serverRequest.attributes().clear();
                        serverRequest.attributes().putAll(nestedRequest.attributes());
                    }

                });
            }).orElseGet(Mono::empty);
        }

        public void accept(RouterFunctions.Visitor visitor) {
            visitor.startNested(this.predicate);
            this.routerFunction.accept(visitor);
            visitor.endNested(this.predicate);
        }
    }

    private static final class DefaultRouterFunction<T extends ServerResponse> extends RouterFunctions.AbstractRouterFunction<T> {
        private final RequestPredicate predicate;
        private final HandlerFunction<T> handlerFunction;

        public DefaultRouterFunction(RequestPredicate predicate, HandlerFunction<T> handlerFunction) {
            Assert.notNull(predicate, "Predicate must not be null");
            Assert.notNull(handlerFunction, "HandlerFunction must not be null");
            this.predicate = predicate;
            this.handlerFunction = handlerFunction;
        }

        public Mono<HandlerFunction<T>> route(ServerRequest request) {
            if (this.predicate.test(request)) {
                if (RouterFunctions.logger.isTraceEnabled()) {
                    String logPrefix = request.exchange().getLogPrefix();
                    RouterFunctions.logger.trace(logPrefix + String.format("Matched %s", this.predicate));
                }

                return Mono.just(this.handlerFunction);
            } else {
                return Mono.empty();
            }
        }

        public void accept(RouterFunctions.Visitor visitor) {
            visitor.route(this.predicate, this.handlerFunction);
        }
    }

    static final class FilteredRouterFunction<T extends ServerResponse, S extends ServerResponse> implements RouterFunction<S> {
        private final RouterFunction<T> routerFunction;
        private final HandlerFilterFunction<T, S> filterFunction;

        public FilteredRouterFunction(RouterFunction<T> routerFunction, HandlerFilterFunction<T, S> filterFunction) {
            this.routerFunction = routerFunction;
            this.filterFunction = filterFunction;
        }

        public Mono<HandlerFunction<S>> route(ServerRequest request) {
            Mono var10000 = this.routerFunction.route(request);
            HandlerFilterFunction var10001 = this.filterFunction;
            var10001.getClass();
            return var10000.map(var10001::apply);
        }

        public void accept(RouterFunctions.Visitor visitor) {
            this.routerFunction.accept(visitor);
        }

        public String toString() {
            return this.routerFunction.toString();
        }
    }

    static final class DifferentComposedRouterFunction extends RouterFunctions.AbstractRouterFunction<ServerResponse> {
        private final RouterFunction<?> first;
        private final RouterFunction<?> second;

        public DifferentComposedRouterFunction(RouterFunction<?> first, RouterFunction<?> second) {
            this.first = first;
            this.second = second;
        }

        public Mono<HandlerFunction<ServerResponse>> route(ServerRequest request) {
            return Flux.concat(new Publisher[]{this.first.route(request), Mono.defer(() -> {
                return this.second.route(request);
            })}).next().map(this::cast);
        }

        private <T extends ServerResponse> HandlerFunction<T> cast(HandlerFunction<?> handlerFunction) {
            return handlerFunction;
        }

        public void accept(RouterFunctions.Visitor visitor) {
            this.first.accept(visitor);
            this.second.accept(visitor);
        }
    }

    static final class SameComposedRouterFunction<T extends ServerResponse> extends RouterFunctions.AbstractRouterFunction<T> {
        private final RouterFunction<T> first;
        private final RouterFunction<T> second;

        public SameComposedRouterFunction(RouterFunction<T> first, RouterFunction<T> second) {
            this.first = first;
            this.second = second;
        }

        public Mono<HandlerFunction<T>> route(ServerRequest request) {
            return Flux.concat(new Publisher[]{this.first.route(request), Mono.defer(() -> {
                return this.second.route(request);
            })}).next();
        }

        public void accept(RouterFunctions.Visitor visitor) {
            this.first.accept(visitor);
            this.second.accept(visitor);
        }
    }

    abstract static class AbstractRouterFunction<T extends ServerResponse> implements RouterFunction<T> {
        AbstractRouterFunction() {
        }

        public String toString() {
            ToStringVisitor visitor = new ToStringVisitor();
            this.accept(visitor);
            return visitor.toString();
        }
    }

    public interface Visitor {
        void startNested(RequestPredicate var1);

        void endNested(RequestPredicate var1);

        void route(RequestPredicate var1, HandlerFunction<?> var2);

        void resources(Function<ServerRequest, Mono<Resource>> var1);

        void unknown(RouterFunction<?> var1);
    }

    public interface Builder {      //构造routerFunction
        RouterFunctions.Builder GET(String var1, HandlerFunction<ServerResponse> var2);
        RouterFunctions.Builder GET(String var1, RequestPredicate var2, HandlerFunction<ServerResponse> var3);

        RouterFunctions.Builder HEAD(String var1, HandlerFunction<ServerResponse> var2);
        RouterFunctions.Builder HEAD(String var1, RequestPredicate var2, HandlerFunction<ServerResponse> var3);

        RouterFunctions.Builder POST(String var1, HandlerFunction<ServerResponse> var2);
        RouterFunctions.Builder POST(String var1, RequestPredicate var2, HandlerFunction<ServerResponse> var3);

        RouterFunctions.Builder PUT(String var1, HandlerFunction<ServerResponse> var2);
        RouterFunctions.Builder PUT(String var1, RequestPredicate var2, HandlerFunction<ServerResponse> var3);

        RouterFunctions.Builder PATCH(String var1, HandlerFunction<ServerResponse> var2);
        RouterFunctions.Builder PATCH(String var1, RequestPredicate var2, HandlerFunction<ServerResponse> var3);

        RouterFunctions.Builder DELETE(String var1, HandlerFunction<ServerResponse> var2);
        RouterFunctions.Builder DELETE(String var1, RequestPredicate var2, HandlerFunction<ServerResponse> var3);

        RouterFunctions.Builder OPTIONS(String var1, HandlerFunction<ServerResponse> var2);
        RouterFunctions.Builder OPTIONS(String var1, RequestPredicate var2, HandlerFunction<ServerResponse> var3);

        RouterFunctions.Builder route(RequestPredicate var1, HandlerFunction<ServerResponse> var2);

        RouterFunctions.Builder add(RouterFunction<ServerResponse> var1);

        RouterFunctions.Builder resources(String var1, Resource var2);
        RouterFunctions.Builder resources(Function<ServerRequest, Mono<Resource>> var1);

        RouterFunctions.Builder nest(RequestPredicate var1, Supplier<RouterFunction<ServerResponse>> var2);
        RouterFunctions.Builder nest(RequestPredicate var1, Consumer<RouterFunctions.Builder> var2);

        RouterFunctions.Builder path(String var1, Supplier<RouterFunction<ServerResponse>> var2);
        RouterFunctions.Builder path(String var1, Consumer<RouterFunctions.Builder> var2);

        RouterFunctions.Builder filter(HandlerFilterFunction<ServerResponse, ServerResponse> var1);
        RouterFunctions.Builder before(Function<ServerRequest, ServerRequest> var1);
        RouterFunctions.Builder after(BiFunction<ServerRequest, ServerResponse, ServerResponse> var1);

        RouterFunctions.Builder onError(Predicate<? super Throwable> var1, BiFunction<? super Throwable, ServerRequest, Mono<ServerResponse>> var2);
        <T extends Throwable> RouterFunctions.Builder onError(Class<T> var1, BiFunction<? super T, ServerRequest, Mono<ServerResponse>> var2);

        RouterFunction<ServerResponse> build();
    }
}

 

 

**********************

RequestPredicate

 

RequestPredicate

@FunctionalInterface
public interface RequestPredicate {
    boolean test(ServerRequest var1);

    default RequestPredicate and(RequestPredicate other) {
        return new AndRequestPredicate(this, other);
    }

    default RequestPredicate negate() {
        return new NegateRequestPredicate(this);
    }

    default RequestPredicate or(RequestPredicate other) {
        return new OrRequestPredicate(this, other);
    }

    default Optional<ServerRequest> nest(ServerRequest request) {
        return this.test(request) ? Optional.of(request) : Optional.empty();
    }

    default void accept(Visitor visitor) {
        visitor.unknown(this);
    }
}

 

RequestPredicates:构造RequestPredicate

public abstract class RequestPredicates {
    private static final Log logger = LogFactory.getLog(RequestPredicates.class);

    public RequestPredicates() {
    }

    public static RequestPredicate all() {
        return (request) -> {
            return true;
        };
    }

    public static RequestPredicate method(HttpMethod httpMethod) {
        return new RequestPredicates.HttpMethodPredicate(httpMethod);
    }

    public static RequestPredicate methods(HttpMethod... httpMethods) {
        return new RequestPredicates.HttpMethodPredicate(httpMethods);
    }

    public static RequestPredicate path(String pattern) {
        Assert.notNull(pattern, "'pattern' must not be null");
        if (!pattern.isEmpty() && !pattern.startsWith("/")) {
            pattern = "/" + pattern;
        }

        return (RequestPredicate)pathPredicates(PathPatternParser.defaultInstance).apply(pattern);
    }

    public static Function<String, RequestPredicate> pathPredicates(PathPatternParser patternParser) {
        Assert.notNull(patternParser, "PathPatternParser must not be null");
        return (pattern) -> {
            return new RequestPredicates.PathPatternPredicate(patternParser.parse(pattern));
        };
    }

    public static RequestPredicate headers(Predicate<Headers> headersPredicate) {
        return new RequestPredicates.HeadersPredicate(headersPredicate);
    }

    public static RequestPredicate contentType(MediaType... mediaTypes) {
        Assert.notEmpty(mediaTypes, "'mediaTypes' must not be empty");
        return new RequestPredicates.ContentTypePredicate(mediaTypes);
    }

    public static RequestPredicate accept(MediaType... mediaTypes) {
        Assert.notEmpty(mediaTypes, "'mediaTypes' must not be empty");
        return new RequestPredicates.AcceptPredicate(mediaTypes);
    }

    public static RequestPredicate GET(String pattern) {
        return method(HttpMethod.GET).and(path(pattern));
    }

    public static RequestPredicate HEAD(String pattern) {
        return method(HttpMethod.HEAD).and(path(pattern));
    }

    public static RequestPredicate POST(String pattern) {
        return method(HttpMethod.POST).and(path(pattern));
    }

    public static RequestPredicate PUT(String pattern) {
        return method(HttpMethod.PUT).and(path(pattern));
    }

    public static RequestPredicate PATCH(String pattern) {
        return method(HttpMethod.PATCH).and(path(pattern));
    }

    public static RequestPredicate DELETE(String pattern) {
        return method(HttpMethod.DELETE).and(path(pattern));
    }

    public static RequestPredicate OPTIONS(String pattern) {
        return method(HttpMethod.OPTIONS).and(path(pattern));
    }

    public static RequestPredicate pathExtension(String extension) {
        Assert.notNull(extension, "'extension' must not be null");
        return new RequestPredicates.PathExtensionPredicate(extension);
    }

    public static RequestPredicate pathExtension(Predicate<String> extensionPredicate) {
        return new RequestPredicates.PathExtensionPredicate(extensionPredicate);
    }

    public static RequestPredicate queryParam(String name, String value) {
        return new RequestPredicates.QueryParamPredicate(name, value);
    }

    public static RequestPredicate queryParam(String name, Predicate<String> predicate) {
        return new RequestPredicates.QueryParamPredicate(name, predicate);
    }

    private static void traceMatch(String prefix, Object desired, @Nullable Object actual, boolean match) {
        if (logger.isTraceEnabled()) {
            logger.trace(String.format("%s \"%s\" %s against value \"%s\"", prefix, desired, match ? "matches" : "does not match", actual));
        }

    }

    private static void restoreAttributes(ServerRequest request, Map<String, Object> attributes) {
        request.attributes().clear();
        request.attributes().putAll(attributes);
    }

    private static Map<String, String> mergePathVariables(Map<String, String> oldVariables, Map<String, String> newVariables) {
        if (!newVariables.isEmpty()) {
            Map<String, String> mergedVariables = new LinkedHashMap(oldVariables);
            mergedVariables.putAll(newVariables);
            return mergedVariables;
        } else {
            return oldVariables;
        }
    }

    private static PathPattern mergePatterns(@Nullable PathPattern oldPattern, PathPattern newPattern) {
        return oldPattern != null ? oldPattern.combine(newPattern) : newPattern;
    }

    private static class SubPathServerRequestWrapper implements ServerRequest {
        private final ServerRequest request;
        private final PathContainer pathContainer;
        private final Map<String, Object> attributes;

        public SubPathServerRequestWrapper(ServerRequest request, PathRemainingMatchInfo info, PathPattern pattern) {
            this.request = request;
            this.pathContainer = new RequestPredicates.SubPathServerRequestWrapper.SubPathContainer(info.getPathRemaining());
            this.attributes = mergeAttributes(request, info.getUriVariables(), pattern);
        }

        private static Map<String, Object> mergeAttributes(ServerRequest request, Map<String, String> pathVariables, PathPattern pattern) {
            Map<String, Object> result = new ConcurrentHashMap(request.attributes());
            result.put(RouterFunctions.URI_TEMPLATE_VARIABLES_ATTRIBUTE, RequestPredicates.mergePathVariables(request.pathVariables(), pathVariables));
            pattern = RequestPredicates.mergePatterns((PathPattern)request.attributes().get(RouterFunctions.MATCHING_PATTERN_ATTRIBUTE), pattern);
            result.put(RouterFunctions.MATCHING_PATTERN_ATTRIBUTE, pattern);
            return result;
        }

        public HttpMethod method() {
            return this.request.method();
        }

        public String methodName() {
            return this.request.methodName();
        }

        public URI uri() {
            return this.request.uri();
        }

        public UriBuilder uriBuilder() {
            return this.request.uriBuilder();
        }

        public String path() {
            return this.pathContainer.value();
        }

        public PathContainer pathContainer() {
            return this.pathContainer;
        }

        public Headers headers() {
            return this.request.headers();
        }

        public MultiValueMap<String, HttpCookie> cookies() {
            return this.request.cookies();
        }

        public Optional<InetSocketAddress> remoteAddress() {
            return this.request.remoteAddress();
        }

        public Optional<InetSocketAddress> localAddress() {
            return this.request.localAddress();
        }

        public List<HttpMessageReader<?>> messageReaders() {
            return this.request.messageReaders();
        }

        public <T> T body(BodyExtractor<T, ? super ServerHttpRequest> extractor) {
            return this.request.body(extractor);
        }

        public <T> T body(BodyExtractor<T, ? super ServerHttpRequest> extractor, Map<String, Object> hints) {
            return this.request.body(extractor, hints);
        }

        public <T> Mono<T> bodyToMono(Class<? extends T> elementClass) {
            return this.request.bodyToMono(elementClass);
        }

        public <T> Mono<T> bodyToMono(ParameterizedTypeReference<T> typeReference) {
            return this.request.bodyToMono(typeReference);
        }

        public <T> Flux<T> bodyToFlux(Class<? extends T> elementClass) {
            return this.request.bodyToFlux(elementClass);
        }

        public <T> Flux<T> bodyToFlux(ParameterizedTypeReference<T> typeReference) {
            return this.request.bodyToFlux(typeReference);
        }

        public Map<String, Object> attributes() {
            return this.attributes;
        }

        public Optional<String> queryParam(String name) {
            return this.request.queryParam(name);
        }

        public MultiValueMap<String, String> queryParams() {
            return this.request.queryParams();
        }

        public Map<String, String> pathVariables() {
            return (Map)this.attributes.getOrDefault(RouterFunctions.URI_TEMPLATE_VARIABLES_ATTRIBUTE, Collections.emptyMap());
        }

        public Mono<WebSession> session() {
            return this.request.session();
        }

        public Mono<? extends Principal> principal() {
            return this.request.principal();
        }

        public Mono<MultiValueMap<String, String>> formData() {
            return this.request.formData();
        }

        public Mono<MultiValueMap<String, Part>> multipartData() {
            return this.request.multipartData();
        }

        public ServerWebExchange exchange() {
            return this.request.exchange();
        }

        public String toString() {
            return this.method() + " " + this.path();
        }

        private static class SubPathContainer implements PathContainer {
            private static final Separator SEPARATOR = () -> {
                return "/";
            };
            private final String value;
            private final List<Element> elements;

            public SubPathContainer(PathContainer original) {
                this.value = prefixWithSlash(original.value());
                this.elements = prependWithSeparator(original.elements());
            }

            private static String prefixWithSlash(String path) {
                if (!path.startsWith("/")) {
                    path = "/" + path;
                }

                return path;
            }

            private static List<Element> prependWithSeparator(List<Element> elements) {
                List<Element> result = new ArrayList(elements);
                if (result.isEmpty() || !(result.get(0) instanceof Separator)) {
                    result.add(0, SEPARATOR);
                }

                return Collections.unmodifiableList(result);
            }

            public String value() {
                return this.value;
            }

            public List<Element> elements() {
                return this.elements;
            }
        }
    }

    static class OrRequestPredicate implements RequestPredicate {
        private final RequestPredicate left;
        private final RequestPredicate right;

        public OrRequestPredicate(RequestPredicate left, RequestPredicate right) {
            Assert.notNull(left, "Left RequestPredicate must not be null");
            Assert.notNull(right, "Right RequestPredicate must not be null");
            this.left = left;
            this.right = right;
        }

        public boolean test(ServerRequest request) {
            Map<String, Object> oldAttributes = new HashMap(request.attributes());
            if (this.left.test(request)) {
                return true;
            } else {
                RequestPredicates.restoreAttributes(request, oldAttributes);
                if (this.right.test(request)) {
                    return true;
                } else {
                    RequestPredicates.restoreAttributes(request, oldAttributes);
                    return false;
                }
            }
        }

        public Optional<ServerRequest> nest(ServerRequest request) {
            Optional<ServerRequest> leftResult = this.left.nest(request);
            return leftResult.isPresent() ? leftResult : this.right.nest(request);
        }

        public void accept(RequestPredicates.Visitor visitor) {
            visitor.startOr();
            this.left.accept(visitor);
            visitor.or();
            this.right.accept(visitor);
            visitor.endOr();
        }

        public String toString() {
            return String.format("(%s || %s)", this.left, this.right);
        }
    }

    static class NegateRequestPredicate implements RequestPredicate {
        private final RequestPredicate delegate;

        public NegateRequestPredicate(RequestPredicate delegate) {
            Assert.notNull(delegate, "Delegate must not be null");
            this.delegate = delegate;
        }

        public boolean test(ServerRequest request) {
            Map<String, Object> oldAttributes = new HashMap(request.attributes());
            boolean result = !this.delegate.test(request);
            if (!result) {
                RequestPredicates.restoreAttributes(request, oldAttributes);
            }

            return result;
        }

        public void accept(RequestPredicates.Visitor visitor) {
            visitor.startNegate();
            this.delegate.accept(visitor);
            visitor.endNegate();
        }

        public String toString() {
            return "!" + this.delegate.toString();
        }
    }

    static class AndRequestPredicate implements RequestPredicate {
        private final RequestPredicate left;
        private final RequestPredicate right;

        public AndRequestPredicate(RequestPredicate left, RequestPredicate right) {
            Assert.notNull(left, "Left RequestPredicate must not be null");
            Assert.notNull(right, "Right RequestPredicate must not be null");
            this.left = left;
            this.right = right;
        }

        public boolean test(ServerRequest request) {
            Map<String, Object> oldAttributes = new HashMap(request.attributes());
            if (this.left.test(request) && this.right.test(request)) {
                return true;
            } else {
                RequestPredicates.restoreAttributes(request, oldAttributes);
                return false;
            }
        }

        public Optional<ServerRequest> nest(ServerRequest request) {
            Optional var10000 = this.left.nest(request);
            RequestPredicate var10001 = this.right;
            var10001.getClass();
            return var10000.flatMap(var10001::nest);
        }

        public void accept(RequestPredicates.Visitor visitor) {
            visitor.startAnd();
            this.left.accept(visitor);
            visitor.and();
            this.right.accept(visitor);
            visitor.endAnd();
        }

        public String toString() {
            return String.format("(%s && %s)", this.left, this.right);
        }
    }

    private static class QueryParamPredicate implements RequestPredicate {
        private final String name;
        private final Predicate<String> valuePredicate;
        @Nullable
        private final String value;

        public QueryParamPredicate(String name, Predicate<String> valuePredicate) {
            Assert.notNull(name, "Name must not be null");
            Assert.notNull(valuePredicate, "Predicate must not be null");
            this.name = name;
            this.valuePredicate = valuePredicate;
            this.value = null;
        }

        public QueryParamPredicate(String name, String value) {
            Assert.notNull(name, "Name must not be null");
            Assert.notNull(value, "Value must not be null");
            this.name = name;
            this.valuePredicate = value::equals;
            this.value = value;
        }

        public boolean test(ServerRequest request) {
            Optional<String> s = request.queryParam(this.name);
            return s.filter(this.valuePredicate).isPresent();
        }

        public void accept(RequestPredicates.Visitor visitor) {
            visitor.queryParam(this.name, this.value != null ? this.value : this.valuePredicate.toString());
        }

        public String toString() {
            return String.format("?%s %s", this.name, this.value != null ? this.value : this.valuePredicate);
        }
    }

    private static class PathExtensionPredicate implements RequestPredicate {
        private final Predicate<String> extensionPredicate;
        @Nullable
        private final String extension;

        public PathExtensionPredicate(Predicate<String> extensionPredicate) {
            Assert.notNull(extensionPredicate, "Predicate must not be null");
            this.extensionPredicate = extensionPredicate;
            this.extension = null;
        }

        public PathExtensionPredicate(String extension) {
            Assert.notNull(extension, "Extension must not be null");
            this.extensionPredicate = (s) -> {
                boolean match = extension.equalsIgnoreCase(s);
                RequestPredicates.traceMatch("Extension", extension, s, match);
                return match;
            };
            this.extension = extension;
        }

        public boolean test(ServerRequest request) {
            String pathExtension = UriUtils.extractFileExtension(request.path());
            return this.extensionPredicate.test(pathExtension);
        }

        public void accept(RequestPredicates.Visitor visitor) {
            visitor.pathExtension(this.extension != null ? this.extension : this.extensionPredicate.toString());
        }

        public String toString() {
            return String.format("*.%s", this.extension != null ? this.extension : this.extensionPredicate);
        }
    }

    private static class AcceptPredicate extends RequestPredicates.HeadersPredicate {
        private final Set<MediaType> mediaTypes;

        public AcceptPredicate(MediaType... mediaTypes) {
            this((Set)(new HashSet(Arrays.asList(mediaTypes))));
        }

        private AcceptPredicate(Set<MediaType> mediaTypes) {
            super((headers) -> {
                List<MediaType> acceptedMediaTypes = acceptedMediaTypes(headers);
                boolean match = acceptedMediaTypes.stream().anyMatch((acceptedMediaType) -> {
                    Stream var10000 = mediaTypes.stream();
                    acceptedMediaType.getClass();
                    return var10000.anyMatch(acceptedMediaType::isCompatibleWith);
                });
                RequestPredicates.traceMatch("Accept", mediaTypes, acceptedMediaTypes, match);
                return match;
            });
            this.mediaTypes = mediaTypes;
        }

        @NonNull
        private static List<MediaType> acceptedMediaTypes(Headers headers) {
            List<MediaType> acceptedMediaTypes = headers.accept();
            if (acceptedMediaTypes.isEmpty()) {
                acceptedMediaTypes = Collections.singletonList(MediaType.ALL);
            } else {
                MediaType.sortBySpecificityAndQuality(acceptedMediaTypes);
            }

            return acceptedMediaTypes;
        }

        public void accept(RequestPredicates.Visitor visitor) {
            visitor.header("Accept", this.mediaTypes.size() == 1 ? ((MediaType)this.mediaTypes.iterator().next()).toString() : this.mediaTypes.toString());
        }

        public String toString() {
            return String.format("Accept: %s", this.mediaTypes.size() == 1 ? ((MediaType)this.mediaTypes.iterator().next()).toString() : this.mediaTypes.toString());
        }
    }

    private static class ContentTypePredicate extends RequestPredicates.HeadersPredicate {
        private final Set<MediaType> mediaTypes;

        public ContentTypePredicate(MediaType... mediaTypes) {
            this((Set)(new HashSet(Arrays.asList(mediaTypes))));
        }

        private ContentTypePredicate(Set<MediaType> mediaTypes) {
            super((headers) -> {
                MediaType contentType = (MediaType)headers.contentType().orElse(MediaType.APPLICATION_OCTET_STREAM);
                boolean match = mediaTypes.stream().anyMatch((mediaType) -> {
                    return mediaType.includes(contentType);
                });
                RequestPredicates.traceMatch("Content-Type", mediaTypes, contentType, match);
                return match;
            });
            this.mediaTypes = mediaTypes;
        }

        public void accept(RequestPredicates.Visitor visitor) {
            visitor.header("Content-Type", this.mediaTypes.size() == 1 ? ((MediaType)this.mediaTypes.iterator().next()).toString() : this.mediaTypes.toString());
        }

        public String toString() {
            return String.format("Content-Type: %s", this.mediaTypes.size() == 1 ? ((MediaType)this.mediaTypes.iterator().next()).toString() : this.mediaTypes.toString());
        }
    }

    private static class HeadersPredicate implements RequestPredicate {
        private final Predicate<Headers> headersPredicate;

        public HeadersPredicate(Predicate<Headers> headersPredicate) {
            Assert.notNull(headersPredicate, "Predicate must not be null");
            this.headersPredicate = headersPredicate;
        }

        public boolean test(ServerRequest request) {
            return CorsUtils.isPreFlightRequest(request.exchange().getRequest()) ? true : this.headersPredicate.test(request.headers());
        }

        public String toString() {
            return this.headersPredicate.toString();
        }
    }

    private static class PathPatternPredicate implements RequestPredicate {
        private final PathPattern pattern;

        public PathPatternPredicate(PathPattern pattern) {
            Assert.notNull(pattern, "'pattern' must not be null");
            this.pattern = pattern;
        }

        public boolean test(ServerRequest request) {
            PathContainer pathContainer = request.pathContainer();
            PathMatchInfo info = this.pattern.matchAndExtract(pathContainer);
            RequestPredicates.traceMatch("Pattern", this.pattern.getPatternString(), request.path(), info != null);
            if (info != null) {
                mergeAttributes(request, info.getUriVariables(), this.pattern);
                return true;
            } else {
                return false;
            }
        }

        private static void mergeAttributes(ServerRequest request, Map<String, String> variables, PathPattern pattern) {
            Map<String, String> pathVariables = RequestPredicates.mergePathVariables(request.pathVariables(), variables);
            request.attributes().put(RouterFunctions.URI_TEMPLATE_VARIABLES_ATTRIBUTE, Collections.unmodifiableMap(pathVariables));
            pattern = RequestPredicates.mergePatterns((PathPattern)request.attributes().get(RouterFunctions.MATCHING_PATTERN_ATTRIBUTE), pattern);
            request.attributes().put(RouterFunctions.MATCHING_PATTERN_ATTRIBUTE, pattern);
        }

        public Optional<ServerRequest> nest(ServerRequest request) {
            return Optional.ofNullable(this.pattern.matchStartOfPath(request.pathContainer())).map((info) -> {
                return new RequestPredicates.SubPathServerRequestWrapper(request, info, this.pattern);
            });
        }

        public void accept(RequestPredicates.Visitor visitor) {
            visitor.path(this.pattern.getPatternString());
        }

        public String toString() {
            return this.pattern.getPatternString();
        }
    }

    private static class HttpMethodPredicate implements RequestPredicate {
        private final Set<HttpMethod> httpMethods;

        public HttpMethodPredicate(HttpMethod httpMethod) {
            Assert.notNull(httpMethod, "HttpMethod must not be null");
            this.httpMethods = EnumSet.of(httpMethod);
        }

        public HttpMethodPredicate(HttpMethod... httpMethods) {
            Assert.notEmpty(httpMethods, "HttpMethods must not be empty");
            this.httpMethods = EnumSet.copyOf(Arrays.asList(httpMethods));
        }

        public boolean test(ServerRequest request) {
            HttpMethod method = method(request);
            boolean match = this.httpMethods.contains(method);
            RequestPredicates.traceMatch("Method", this.httpMethods, method, match);
            return match;
        }

        @Nullable
        private static HttpMethod method(ServerRequest request) {
            if (CorsUtils.isPreFlightRequest(request.exchange().getRequest())) {
                String accessControlRequestMethod = request.headers().firstHeader("Access-Control-Request-Method");
                return HttpMethod.resolve(accessControlRequestMethod);
            } else {
                return request.method();
            }
        }

        public void accept(RequestPredicates.Visitor visitor) {
            visitor.method(Collections.unmodifiableSet(this.httpMethods));
        }

        public String toString() {
            return this.httpMethods.size() == 1 ? ((HttpMethod)this.httpMethods.iterator().next()).toString() : this.httpMethods.toString();
        }
    }

    public interface Visitor {
        void method(Set<HttpMethod> var1);

        void path(String var1);
        void pathExtension(String var1);

        void header(String var1, String var2);
        void queryParam(String var1, String var2);

        void startAnd();
        void and();
        void endAnd();

        void startOr();
        void or();
        void endOr();

        void startNegate();
        void endNegate();

        void unknown(RequestPredicate var1);
    }
}

 

**********************

HandlerFunction

 

HandlerFunction

@FunctionalInterface
public interface HandlerFunction<T extends ServerResponse> {
    Mono<T> handle(ServerRequest var1);
}

 

ServerRequest

public interface ServerRequest {
    @Nullable
    default HttpMethod method() {
        return HttpMethod.resolve(this.methodName());
    }

    String methodName();

    URI uri();
    UriBuilder uriBuilder();

    default String path() {
        return this.uri().getRawPath();
    }

    default PathContainer pathContainer() {
        return PathContainer.parsePath(this.path());
    }

    ServerRequest.Headers headers();

    MultiValueMap<String, HttpCookie> cookies();

    Optional<InetSocketAddress> remoteAddress();
    Optional<InetSocketAddress> localAddress();

    List<HttpMessageReader<?>> messageReaders();

    <T> T body(BodyExtractor<T, ? super ServerHttpRequest> var1);
    <T> T body(BodyExtractor<T, ? super ServerHttpRequest> var1, Map<String, Object> var2);

    <T> Mono<T> bodyToMono(Class<? extends T> var1);
    <T> Mono<T> bodyToMono(ParameterizedTypeReference<T> var1);

    <T> Flux<T> bodyToFlux(Class<? extends T> var1);
    <T> Flux<T> bodyToFlux(ParameterizedTypeReference<T> var1);

    default Optional<Object> attribute(String name) {
        return Optional.ofNullable(this.attributes().get(name));
    }

    Map<String, Object> attributes();

    default Optional<String> queryParam(String name) {
        List<String> queryParamValues = (List)this.queryParams().get(name);
        if (CollectionUtils.isEmpty(queryParamValues)) {
            return Optional.empty();
        } else {
            String value = (String)queryParamValues.get(0);
            if (value == null) {
                value = "";
            }

            return Optional.of(value);
        }
    }

    MultiValueMap<String, String> queryParams();

    default String pathVariable(String name) {
        Map<String, String> pathVariables = this.pathVariables();
        if (pathVariables.containsKey(name)) {
            return (String)this.pathVariables().get(name);
        } else {
            throw new IllegalArgumentException("No path variable with name \"" + name + "\" available");
        }
    }

    Map<String, String> pathVariables();

    Mono<WebSession> session();

    Mono<? extends Principal> principal();

    Mono<MultiValueMap<String, String>> formData();
    Mono<MultiValueMap<String, Part>> multipartData();

    ServerWebExchange exchange();

    default Mono<ServerResponse> checkNotModified(Instant lastModified) {
        Assert.notNull(lastModified, "LastModified must not be null");
        return DefaultServerRequest.checkNotModified(this.exchange(), lastModified, (String)null);
    }

    default Mono<ServerResponse> checkNotModified(String etag) {
        Assert.notNull(etag, "Etag must not be null");
        return DefaultServerRequest.checkNotModified(this.exchange(), (Instant)null, etag);
    }

    default Mono<ServerResponse> checkNotModified(Instant lastModified, String etag) {
        Assert.notNull(lastModified, "LastModified must not be null");
        Assert.notNull(etag, "Etag must not be null");
        return DefaultServerRequest.checkNotModified(this.exchange(), lastModified, etag);
    }

    static ServerRequest create(ServerWebExchange exchange, List<HttpMessageReader<?>> messageReaders) {
        return new DefaultServerRequest(exchange, messageReaders);
    }

    static ServerRequest.Builder from(ServerRequest other) {
        return new DefaultServerRequestBuilder(other);
    }

    public interface Builder {
        ServerRequest.Builder method(HttpMethod var1);

        ServerRequest.Builder uri(URI var1);

        ServerRequest.Builder header(String var1, String... var2);
        ServerRequest.Builder headers(Consumer<HttpHeaders> var1);

        ServerRequest.Builder cookie(String var1, String... var2);
        ServerRequest.Builder cookies(Consumer<MultiValueMap<String, HttpCookie>> var1);

        ServerRequest.Builder body(Flux<DataBuffer> var1);
        ServerRequest.Builder body(String var1);

        ServerRequest.Builder attribute(String var1, Object var2);
        ServerRequest.Builder attributes(Consumer<Map<String, Object>> var1);

        ServerRequest build();
    }

    public interface Headers {
        List<MediaType> accept();
        List<Charset> acceptCharset();
        List<LanguageRange> acceptLanguage();

        OptionalLong contentLength();
        Optional<MediaType> contentType();

        @Nullable
        InetSocketAddress host();

        List<HttpRange> range();

        List<String> header(String var1);

        @Nullable
        default String firstHeader(String headerName) {
            List<String> list = this.header(headerName);
            return list.isEmpty() ? null : (String)list.get(0);
        }

        HttpHeaders asHttpHeaders();
    }
}

 

ServerResponse

public interface ServerResponse {
    HttpStatus statusCode();

    int rawStatusCode();

    HttpHeaders headers();

    MultiValueMap<String, ResponseCookie> cookies();

    Mono<Void> writeTo(ServerWebExchange var1, ServerResponse.Context var2);

    static ServerResponse.BodyBuilder from(ServerResponse other) {
        return new DefaultServerResponseBuilder(other);
    }

    static ServerResponse.BodyBuilder status(HttpStatus status) {
        return new DefaultServerResponseBuilder(status);
    }

    static ServerResponse.BodyBuilder status(int status) {
        return new DefaultServerResponseBuilder(status);
    }

    static ServerResponse.BodyBuilder ok() {
        return status(HttpStatus.OK);
    }

    static ServerResponse.BodyBuilder created(URI location) {
        ServerResponse.BodyBuilder builder = status(HttpStatus.CREATED);
        return (ServerResponse.BodyBuilder)builder.location(location);
    }

    static ServerResponse.BodyBuilder accepted() {
        return status(HttpStatus.ACCEPTED);
    }

    static ServerResponse.HeadersBuilder<?> noContent() {
        return status(HttpStatus.NO_CONTENT);
    }

    static ServerResponse.BodyBuilder seeOther(URI location) {
        ServerResponse.BodyBuilder builder = status(HttpStatus.SEE_OTHER);
        return (ServerResponse.BodyBuilder)builder.location(location);
    }

    static ServerResponse.BodyBuilder temporaryRedirect(URI location) {
        ServerResponse.BodyBuilder builder = status(HttpStatus.TEMPORARY_REDIRECT);
        return (ServerResponse.BodyBuilder)builder.location(location);
    }

    static ServerResponse.BodyBuilder permanentRedirect(URI location) {
        ServerResponse.BodyBuilder builder = status(HttpStatus.PERMANENT_REDIRECT);
        return (ServerResponse.BodyBuilder)builder.location(location);
    }

    static ServerResponse.BodyBuilder badRequest() {
        return status(HttpStatus.BAD_REQUEST);
    }

    static ServerResponse.HeadersBuilder<?> notFound() {
        return status(HttpStatus.NOT_FOUND);
    }

    static ServerResponse.BodyBuilder unprocessableEntity() {
        return status(HttpStatus.UNPROCESSABLE_ENTITY);
    }

    public interface Context {
        List<HttpMessageWriter<?>> messageWriters();

        List<ViewResolver> viewResolvers();
    }

    public interface BodyBuilder extends ServerResponse.HeadersBuilder<ServerResponse.BodyBuilder> {
        ServerResponse.BodyBuilder contentLength(long var1);
        ServerResponse.BodyBuilder contentType(MediaType var1);

        ServerResponse.BodyBuilder hint(String var1, Object var2);
        ServerResponse.BodyBuilder hints(Consumer<Map<String, Object>> var1);

        Mono<ServerResponse> bodyValue(Object var1);

        <T, P extends Publisher<T>> Mono<ServerResponse> body(P var1, Class<T> var2);
        <T, P extends Publisher<T>> Mono<ServerResponse> body(P var1, ParameterizedTypeReference<T> var2);

        Mono<ServerResponse> body(Object var1, Class<?> var2);
        Mono<ServerResponse> body(Object var1, ParameterizedTypeReference<?> var2);
        Mono<ServerResponse> body(BodyInserter<?, ? super ServerHttpResponse> var1);

        /** @deprecated */
        @Deprecated
        Mono<ServerResponse> syncBody(Object var1);

        Mono<ServerResponse> render(String var1, Object... var2);
        Mono<ServerResponse> render(String var1, Map<String, ?> var2);
    }

    public interface HeadersBuilder<B extends ServerResponse.HeadersBuilder<B>> {
        B header(String var1, String... var2);
        B headers(Consumer<HttpHeaders> var1);

        B cookie(ResponseCookie var1);
        B cookies(Consumer<MultiValueMap<String, ResponseCookie>> var1);

        B allow(HttpMethod... var1);
        B allow(Set<HttpMethod> var1);

        B eTag(String var1);

        B lastModified(ZonedDateTime var1);
        B lastModified(Instant var1);

        B location(URI var1);

        B cacheControl(CacheControl var1);

        B varyBy(String... var1);

        Mono<ServerResponse> build();
        Mono<ServerResponse> build(Publisher<Void> var1);
        Mono<ServerResponse> build(BiFunction<ServerWebExchange, ServerResponse.Context, Mono<Void>> var1);
    }
}

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Spring Boot WebFlux是Spring Boot框架的一部分,它提供了一种响应式编程模型,可以用于构建高性能、高可伸缩性的Web应用程序。WebFlux基于Reactor框架,它支持异步和非阻塞I/O操作,可以处理大量的并发请求。WebFlux还提供了一些有用的功能,如函数式端点、WebSockets、HTTP/2等。 ### 回答2: Spring Boot WebFlux是Spring Framework 5.0版本中新增的模块,它基于响应式编程的思想,提供了一种非常高效和易于扩展的方式来开发异步非阻塞的Web应用程序。 WebFlux的核心是基于Reactor和Netty的异步IO模型,因此它可以非常高效地处理大量的并发请求。Reactor是一个响应式编程框架,它可以将异步事件流进行处理,并且在需要的时候进行背压流控制,确保应用程序不会因为过多的请求而崩溃或溢出。 在WebFlux中,我们可以使用注解方式来定义RESTful API,并且使用函数式编程方式来处理请求和响应。这种方式非常简洁和高效,可以大大减少重复代码的编写和维护成本。 另外,WebFlux还提供了一些非常强大的功能,例如集成了Spring Security,可以轻松地实现基于角色和权限的访问控制;还提供了Reactive Data Access,可以方便地访问各种数据库、缓存和消息队列等数据源。 在开发Web应用程序时,我们常常会遇到的一个问题是如何处理长连接。在传统的Servlet模型下,我们通常会创建一个新的线程来处理每个连接,这样会导致线程资源的浪费。但是在WebFlux中,我们可以使用WebSocket和Server-Sent Events等技术来处理长连接,这种方式可以在不创建新线程的情况下处理大量的并发连接,大大提高了应用程序的性能和稳定性。 总之,Spring Boot WebFlux是一种非常优秀的Web开发框架,它提供了一种高效、易于扩展和具有优异性能的方式来开发异步非阻塞的Web应用程序。如果你希望开发出高性能、高可用性的Web应用程序,那么WebFlux是一个非常不错的选择。 ### 回答3: Spring Boot Webflux是Spring Boot框架中的一项新功能,它是一种基于反应式编程思想的异步编程模型。它主要基于Reactor库,其核心是FluxMono类型,用于管理流和单个值异步处理。 相比于传统的Spring MVC框架,Webflux提供了更高的性能和更好的可伸缩性,可以有效地处理数百万请求。Webflux非常适合处理高并发、数据流处理、I/O密集型的应用,如实时通信、监控、数据处理等。 Webflux提供了许多新的特性,例如非阻塞I/O、函数式端点、响应式数据流处理、事件驱动I/O等。这些特性都极大地提高了应用程序的效率和可扩展性,同时也使代码更加简单和易于维护。 Webflux还提供了一些常见的数据存储支持,如MongoDB、Redis等。它支持Spring Boot自动配置和依赖性注入模式,可以帮助快速构建和部署反应式应用程序。 总之,Spring Boot Webflux是一个很好的选择,特别适合处理大量并发请求、I/O密集型的应用程序,能够极大地提高应用程序的效率和性能,同时也提高了可维护性和扩展性,具有广泛的应用前景。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值