在前文中,我們介紹了Spring Cloud Gateway內置了一系列的全局過濾器,本文介紹如何自定義全局過濾器。
自定義全局過濾需要實現GlobalFilter 接口,該接口和 GatewayFilter 有一樣的方法定義,只不過 GlobalFilter 的實例會作用於所有的路由。
自定義全局過濾器
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
/**
* 自定義全局過濾器
*/
@Slf4j
@Component
public class CustomizeGlobalFilter implements GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String path = exchange.getRequest().getURI().getPath();
log.info("[CustomizeGlobalFilter] 訪問的接口:{}", path);
long start = System.currentTimeMillis();
return chain.filter(exchange)
// then的內容會在過濾器返回的時候執行,即最后執行
.then(Mono.fromRunnable(() ->
log.info("[ {} ] 接口的訪問耗時:{} /ms", path, System.currentTimeMillis() - start)
));
}
}
上述代碼中,我們使用@Component注解使該全局過濾器生效。還有一種方式,就是使用一個專門的配置類去實例化這些全局過濾器並交給Spring容器管理,代碼如下:
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
@Slf4j
@Configuration
public class FilterConfig {
@Bean
// 該注解用於指定過濾器的執行順序,數字越小越優先執行
@Order(Ordered.HIGHEST_PRECEDENCE)
public GlobalFilter myGlobalFilter(){
log.info("create myGlobalFilter...");
return new MyGlobalFilter();
}
}