前言
无意中留心的一串代码,就浅浅的挖了一下,发现还挺有意思。
背景
微服务的网关在配置拦截器filter用于登录校验时,一般把拿到的数据会用请求头的形式存到ServerWebExchange exchange里,然后由网关发给服务,服务再从请求头里拿。我在添加请求头的时候,发现这个方法有一种莫名的魔力,让我忍不住CTRL+⇧
开始
废话不多说,让我进去看看
具体方法:
//创建一个名为userId的请求头,把数据id存进去
exchange.mutate().request((r -> r.header("userId", id))).build();
这里exchange.mutate()返回一个ServerWebExchange.Builder内部接口
request()方法正是接口一个抽象方法
public interface ServerWebExchange {
default Builder mutate() {
return new DefaultServerWebExchangeBuilder(this);
}
public interface Builder {//内部接口
Builder request(Consumer<ServerHttpRequest.Builder> requestBuilderConsumer);
}
}
有趣的来了,这个Consumer<ServerHttpRequest.Builder> requestBuilderConsumer是什么,没见过,CTRL+⇧
@FunctionalInterface
public interface Consumer<T> {
/**
* Performs this operation on the given argument.
*
* @param t the input argument
*/
/**
*对给定的参数执行此操作。
*
*@param输入参数
*/
void accept(T t);
/**
* Returns a composed {@code Consumer} that performs, in sequence, this
* operation followed by the {@code after} operation. If performing either
* operation throws an exception, it is relayed to the caller of the
* composed operation. If performing this operation throws an exception,
* the {@code after} operation will not be performed.
*
* @param after the operation to perform after this operation
* @return a composed {@code Consumer} that performs in sequence this
* operation followed by the {@code after} operation
* @throws NullPointerException if {@code after} is null
*/
/**
*返回一个组合的{@code Consumer},它按顺序执行以下操作
*操作之后是{@code after}操作。如果执行以下任一操作
*操作抛出一个异常,它被中继到调用者
*组合操作。如果执行此操作会引发异常,
*将不会执行{@code after}操作。
*
*此操作后要执行的操作后的@param
*@返回一个按顺序执行以下操作的组合{@code Consumer}
*操作之后是{@code after}操作
*如果{@code after}为null,则@抛出NullPointerException
*/
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}
又是一个接口,上面还有说明
-
void accept(T t);一个抽象方法没有返回值,应该就是与(r -> r.header("userId", id))对应
-
andThen(Consumer<? super T> after)先按下不表
从第一方法我们能看到
accept(T t)方法没有返回值,那么request()方法调用Lambda表达式重写的accept(T t)是没有值。
所以:exchange.mutate() == exchange.mutate().request() ?
当然,其中肯定有变化,不然调这个凑代码量吗(感觉发现摸鱼小技巧,嘿嘿嘿嘿)
public interface Builder {//内部接口
Builder request(Consumer<ServerHttpRequest.Builder> requestBuilderConsumer);
}
实现类:
public ServerWebExchange.Builder request(Consumer<ServerHttpRequest.Builder> consumer) {
ServerHttpRequest.Builder builder = this.delegate.getRequest().mutate();
consumer.accept(builder);
return this.request(builder.build());
}
这里的泛型是ServerHttpRequest.Builder,CTRL+⇧
public interface ServerHttpRequest extends HttpRequest, ReactiveHttpInputMessage {
public interface Builder {
Builder header(String headerName, String... headerValues);
}
}
又是一个内部接口抽象方法
而这个方法的实现是:
class DefaultServerHttpRequestBuilder implements ServerHttpRequest.Builder {
public ServerHttpRequest.Builder header(String headerName, String... headerValues) {
this.headers.put(headerName, Arrays.asList(headerValues));
return this;
}
}
这个类和方法的设计允许开发者通过链式调用的方式构建复杂的HTTP请求,同时添加多个请求头。
那这里问题来了,绕了一个圈,还是没有发现谁在添加请求头
我们退到前面exchange.mutate() == exchange.mutate().request()
先看exchange.mutate()
default Builder mutate() {
return new DefaultServerWebExchangeBuilder(this);
}
CTRL+⇧ 进入 DefaultServerWebExchangeBuilder
DefaultServerWebExchangeBuilder(ServerWebExchange delegate) {
Assert.notNull(delegate, "Delegate is required");
this.delegate = delegate;
}
没看懂对吧,再给你看看exchange.mutate().request()的实现类
public ServerWebExchange.Builder request(Consumer<ServerHttpRequest.Builder> consumer) {
ServerHttpRequest.Builder builder = this.delegate.getRequest().mutate();
consumer.accept(builder);
return this.request(builder.build());
}
this.delegate,没错这两个在一个类里面DefaultServerWebExchangeBuilder
一个构造方法,一个实现方法
自此,完成闭环
PS:第一次发到上面来,平常都是私下写着玩,中间明显写嗨了。而且还可以继续挖着玩,比如一次添加多个请求头
谢谢!