SpringCloud Gateway中的一处适配器模式的应用

56 阅读1分钟

SpringCloud gateway中有两种过滤器,路由过滤器(接口为GatewayFilter)和全局过滤器(接口为GlobalFilter);
路由过滤器GatewayFilter的定义:

public interface GatewayFilter {

	/**
	 * 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);

} 

全局过滤器GlobalFilter的定义:

public interface GlobalFilter {

	/**
	 * 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);

}

在FilteringWebHandler中会对所有的路由过滤器和全局过滤器进行调用,封装了一个DefaultGatewayFilterChain类,在这个类中统一对路由过滤器和全局过滤器进行调用,但是他们分属不同的接口,这里采用了适配器模式,适配接口GatewayFilterAdapter完成了将GlobalFilter接口适配成GatewayFilter;

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);
    }
}

这样在FilteringWebHandler中就可以将这两种过滤器存放到一个List中:

public class FilteringWebHandler implements WebHandler {
    /**
     * 全局过滤器
     */
	private final List<GatewayFilter> globalFilters;

	public FilteringWebHandler(List<GlobalFilter> globalFilters) {
		this.globalFilters = loadFilters(globalFilters);
	}

	private static List<GatewayFilter> loadFilters(List<GlobalFilter> filters) {
		return filters.stream()
				.map(filter -> {
					GatewayFilterAdapter gatewayFilter = new GatewayFilterAdapter(filter);
					if (filter instanceof Ordered) {
						int order = ((Ordered) filter).getOrder();
						return new OrderedGatewayFilter(gatewayFilter, order);
					}
					return gatewayFilter;
				}).collect(Collectors.toList());
	}
}

在DefaultGatewayFilterChain.filter方法中就可以用同样的方式调用:

private static class DefaultGatewayFilterChain implements GatewayFilterChain {
	private int index;
	private final List<GatewayFilter> filters;

	public DefaultGatewayFilterChain(List<GatewayFilter> filters) {
		this.filters = filters;
	}

	@Override
	public Mono<Void> filter(ServerWebExchange exchange) {
		if (this.index < filters.size()) {
			GatewayFilter filter = filters.get(this.index++);
			return filter.filter(exchange, this);
		} else {
			return Mono.empty(); // complete
		}
	}
}