詳解SpringCloud Gateway之過濾器GatewayFilter
在Spring-Cloud-Gateway之請求處理流程文中我們了解最終網(wǎng)關(guān)是將請求交給過濾器鏈表進行處理,接下來我們閱讀Spring-Cloud-Gateway的整個過濾器類結(jié)構(gòu)以及主要功能
通過源碼可以看到Spring-Cloud-Gateway的filter包中吉接口有如下三個,GatewayFilter,GlobalFilter,GatewayFilterChain,下來我依次閱讀接口的主要實現(xiàn)功能。
GatewayFilterChain
類圖

代碼
/**
* 網(wǎng)關(guān)過濾鏈表接口
* 用于過濾器的鏈式調(diào)用
* Contract to allow a {@link WebFilter} to delegate to the next in the chain.
*
* @author Rossen Stoyanchev
* @since 5.0
*/
public interface GatewayFilterChain {
/**
* 鏈表啟動調(diào)用入口方法
* Delegate to the next {@code WebFilter} in the chain.
* @param exchange the current server exchange
* @return {@code Mono<Void>} to indicate when request handling is complete
*/
Mono<Void> filter(ServerWebExchange exchange);
}
/**
* 網(wǎng)關(guān)過濾的鏈表,用于過濾器的鏈式調(diào)用
* 過濾器鏈表接口的默認實現(xiàn),
* 包含2個構(gòu)建函數(shù):
* 1.集合參數(shù)構(gòu)建用于初始化吧構(gòu)建鏈表
* 2. index,parent參數(shù)用于構(gòu)建當前執(zhí)行過濾對應的下次執(zhí)行的鏈表
*/
private static class DefaultGatewayFilterChain implements GatewayFilterChain {
/**
* 當前過濾執(zhí)行過濾器在集合中索引
*/
private final int index;
/**
* 過濾器集合
*/
private final List<GatewayFilter> filters;
public DefaultGatewayFilterChain(List<GatewayFilter> filters) {
this.filters = filters;
this.index = 0;
}
/**
* 構(gòu)建
* @param parent 上一個執(zhí)行過濾器對應的FilterChain
* @param index 當前要執(zhí)行過濾器的索引
*/
private DefaultGatewayFilterChain(DefaultGatewayFilterChain parent, int index) {
this.filters = parent.getFilters();
this.index = index;
}
public List<GatewayFilter> getFilters() {
return filters;
}
/**
* @param exchange the current server exchange
* @return
*/
@Override
public Mono<Void> filter(ServerWebExchange exchange) {
return Mono.defer(() -> {
if (this.index < filters.size()) {
//獲取當前索引的過濾器
GatewayFilter filter = filters.get(this.index);
//構(gòu)建當前索引的下一個過濾器的FilterChain
DefaultGatewayFilterChain chain = new DefaultGatewayFilterChain(this, this.index + 1);
//調(diào)用過濾器的filter方法執(zhí)行過濾器
return filter.filter(exchange, chain);
} else {
//當前索引大于等于過濾集合大小,標識所有鏈表都已執(zhí)行完畢,返回空
return Mono.empty(); // complete
}
});
}
}
過濾器的GatewayFilterChain 執(zhí)行順序
- 通過GatewayFilter集合構(gòu)建頂層的GatewayFilterChain
- 調(diào)用頂層GatewayFilterChain,獲取第一個Filter,并創(chuàng)建下一個Filter索引對應的GatewayFilterChain
- 調(diào)用filter的filter方法執(zhí)行當前filter,并將下次要執(zhí)行的filter對應GatewayFilterChain傳入。
GatewayFilter
類圖

/**
* 網(wǎng)關(guān)路由過濾器,
* Contract for interception-style, chained processing of Web requests that may
* be used to implement cross-cutting, application-agnostic requirements such
* as security, timeouts, and others. Specific to a Gateway
*
* Copied from WebFilter
*
* @author Rossen Stoyanchev
* @since 5.0
*/
public interface GatewayFilter extends ShortcutConfigurable {
String NAME_KEY = "name";
String VALUE_KEY = "value";
/**
* 過濾器執(zhí)行方法
* Process the Web request and (optionally) delegate to the next
* {@code WebFilter} through the given {@link GatewayFilterChain}.
* @param exchange the current server exchange
* @param chain provides a way to delegate to the next filter
* @return {@code Mono<Void>} to indicate when request processing is complete
*/
Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);
}
網(wǎng)關(guān)過濾器接口,有且只有一個方法filter,執(zhí)行當前過濾器,并在此方法中決定過濾器鏈表是否繼續(xù)往下執(zhí)行,接下來我們看下幾個主要的功能實現(xiàn)類
OrderedGatewayFilter
/**
* 排序的網(wǎng)關(guān)路由過濾器,用于包裝真實的網(wǎng)關(guān)過濾器,已達到過濾器可排序
* @author Spencer Gibb
*/
public class OrderedGatewayFilter implements GatewayFilter, Ordered {
//目標過濾器
private final GatewayFilter delegate;
//排序字段
private final int order;
public OrderedGatewayFilter(GatewayFilter delegate, int order) {
this.delegate = delegate;
this.order = order;
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
return this.delegate.filter(exchange, chain);
}
}
OrderedGatewayFilter實現(xiàn)類主要目的是為了將目標過濾器包裝成可排序的對象類型。是目標過濾器的包裝類
GatewayFilterAdapter
/**
* 全局過濾器的包裝類,將全局路由包裝成統(tǒng)一的網(wǎng)關(guān)過濾器
*/
private static class GatewayFilterAdapter implements GatewayFilter {
/**
* 全局過濾器
*/
private final GlobalFilter delegate;
public GatewayFilterAdapter(GlobalFilter delegate) {
this.delegate = delegate;
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
return this.delegate.filter(exchange, chain);
}
}
GatewayFilterAdapter實現(xiàn)類主要目的是為了將GlobalFilter過濾器包裝成GatewayFilter類型的對應。是GlobalFilter過濾器的包裝類
GlobalFilter

GlobalFilter 為請求業(yè)務以及路由的URI轉(zhuǎn)換為真實業(yè)務服務的請求地址的核心過濾器,不需要配置,模式系統(tǒng)初始化時加載,并作用在每個路由上。
初始化加載,通過GatewayAutoConfiguration自動創(chuàng)建
GatewayAutoConfiguration 類
/**
* 全局過濾器,用戶通過HttpClient轉(zhuǎn)發(fā)請求
* @param httpClient
* @param headersFilters
* @return
*/
@Bean
public NettyRoutingFilter routingFilter(HttpClient httpClient,
ObjectProvider<List<HttpHeadersFilter>> headersFilters) {
return new NettyRoutingFilter(httpClient, headersFilters);
}
/**
* 全局的過濾器,用戶將HttpClient客戶端轉(zhuǎn)發(fā)請求的響應寫入到原始的請求響應中
* @param properties
* @return
*/
@Bean
public NettyWriteResponseFilter nettyWriteResponseFilter(GatewayProperties properties) {
return new NettyWriteResponseFilter(properties.getStreamingMediaTypes());
}
GatewayLoadBalancerClientAutoConfiguration 類
/**
* 全局過濾器,用于在通過負載均衡客戶端選擇服務實例信息
* @param client
* @return
*/
@Bean
@ConditionalOnBean(LoadBalancerClient.class)
public LoadBalancerClientFilter loadBalancerClientFilter(LoadBalancerClient client) {
return new LoadBalancerClientFilter(client);
}
GlobalFilter轉(zhuǎn)換成GatewayFilter,并作用于每個路由上,在FilteringWebHandler實現(xiàn)
FilteringWebHandler類
/**
* 包裝加載全局的過濾器,將全局過濾器包裝成GatewayFilter
* @param filters
* @return
*/
private static List<GatewayFilter> loadFilters(List<GlobalFilter> filters) {
return filters.stream()
.map(filter -> {
//將所有的全局過濾器包裝成網(wǎng)關(guān)過濾器
GatewayFilterAdapter gatewayFilter = new GatewayFilterAdapter(filter);
//判斷全局過濾器是否實現(xiàn)了可排序接口
if (filter instanceof Ordered) {
int order = ((Ordered) filter).getOrder();
//包裝成可排序的網(wǎng)關(guān)過濾器
return new OrderedGatewayFilter(gatewayFilter, order);
}
return gatewayFilter;
}).collect(Collectors.toList());
}
@Override
public Mono<Void> handle(ServerWebExchange exchange) {
//獲取請求上下文設置的路由實例
Route route = exchange.getRequiredAttribute(GATEWAY_ROUTE_ATTR);
//獲取路由定義下的網(wǎng)關(guān)過濾器集合
List<GatewayFilter> gatewayFilters = route.getFilters();
//組合全局的過濾器與路由配置的過濾器
List<GatewayFilter> combined = new ArrayList<>(this.globalFilters);
//添加路由配置過濾器到集合尾部
combined.addAll(gatewayFilters);
//對過濾器進行排序
//TODO: needed or cached?
AnnotationAwareOrderComparator.sort(combined);
logger.debug("Sorted gatewayFilterFactories: "+ combined);
//創(chuàng)建過濾器鏈表對其進行鏈式調(diào)用
return new DefaultGatewayFilterChain(combined).filter(exchange);
}
loadFilters方法是將全局路由使用GatewayFilterAdapter包裝成GatewayFilter
handle方法
- 獲取當前請求使用的路由Route
- 獲取路由配置的過濾器集合route.getFilters()
- 合并全過濾器與路由配置過濾器combined
- 對過濾器排序AnnotationAwareOrderComparator.sort
- 通過過濾器集合構(gòu)建頂級鏈表DefaultGatewayFilterChain,并對其當前請求調(diào)用鏈表的filter方法。
==備注==:
Spring-Cloud-Gateway的過濾器接口分為兩種:
- GlobalFilter : 全局過濾器,不需要在配置文件中配置,作用在所有的路由上,最終通過GatewayFilterAdapter包裝成GatewayFilterChain可識別的過濾器
- GatewayFilter : 需要通過spring.cloud.routes.filters 配置在具體路由下,只作用在當前路由上或通過spring.cloud.default-filters配置在全局,作用在所有路由上
至此,網(wǎng)關(guān)過濾器的整個結(jié)構(gòu)以及加載使用流程源碼已經(jīng)閱讀完畢,下篇重點學習下路由配置的過濾器加載創(chuàng)建流程
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Spring事件監(jiān)聽器ApplicationListener源碼詳解
這篇文章主要介紹了Spring事件監(jiān)聽器ApplicationListener源碼詳解,ApplicationEvent以及Listener是Spring為我們提供的一個事件監(jiān)聽、訂閱的實現(xiàn),內(nèi)部實現(xiàn)原理是觀察者設計模式,需要的朋友可以參考下2023-05-05
IntelliJ IDEA Run時報“無效的源發(fā)行版:16“錯誤問題及解決方法
這篇文章主要介紹了IntelliJ IDEA Run時報“無效的源發(fā)行版:16“錯誤問題及解決方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-05-05
Windows 10上JDK環(huán)境安裝配置圖文教程
這篇文章主要為大家詳細介紹了Windows 10上JDK環(huán)境安裝配置圖文教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-03-03

