RouteLocator (路由定位器)
RouteLocator 能够直接自定义路由( org.springframework.cloud.gateway.route.Route ) ,也能够经过 RouteDefinitionRouteLocator 获取 RouteDefinition ,并转换成 Route 。
RoutePredicateHandlerMapping 使用 RouteLocator 得到 Route 信息。
Route :web
id 属性,ID 编号,惟一。
predicates 属性,谓语数组。请求经过 predicates 判断是否匹配。
filters 属性,过滤器数组。
uri 属性,路由向的 URI 。
order 属性,顺序。当请求匹配到多个路由时,使用顺序小的。
Route 提供 routeDefinition RouteDefinition 建立对象,代码以下 :spring
public static Builder builder(RouteDefinition routeDefinition) { return new Builder() .id(routeDefinition.getId()) .uri(routeDefinition.getUri()) .order(routeDefinition.getOrder()); }
predicate / gatewayFilters 属性,须要调用 Builder 相关方法进行设置。数组
org.springframework.cloud.gateway.route.RouteLocator ,路由定位器接口,定义得到路由数组的方法。代码以下 :缓存
public interface RouteLocator { Flux<Route> getRoutes(); }
在上文中,咱们也看到了 RouteLocator 的多个实现类,类图以下 :app
org.springframework.cloud.gateway.route.CompositeRouteLocator ,组合多种 RouteLocator 的实现类,为 RoutePredicateHandlerMapping 提供统一入口访问路由。代码以下 :ide
public class CompositeRouteLocator implements RouteLocator { private final Flux<RouteLocator> delegates; public CompositeRouteLocator(Flux<RouteLocator> delegates) { this.delegates = delegates; } @Override public Flux<Route> getRoutes() { return this.delegates.flatMap(RouteLocator::getRoutes); } }
#getRoutes() 方法,提供统一方法,将组合的 delegates 的路由所有返回。svg
org.springframework.cloud.gateway.route.CachingRouteLocator ,缓存路由的 RouteLocator 实现类。RoutePredicateHandlerMapping 调用 CachingRouteLocator 的 RouteLocator#getRoutes() 方法,获取路由。ui
CachingRouteLocator 代码以下 :this
public class CachingRouteLocator implements RouteLocator { private final RouteLocator delegate; /** * 路由缓存 */ private final AtomicReference<List<Route>> cachedRoutes = new AtomicReference<>(); public CachingRouteLocator(RouteLocator delegate) { this.delegate = delegate; this.cachedRoutes.compareAndSet(null, collectRoutes()); } @Override public Flux<Route> getRoutes() { return Flux.fromIterable(this.cachedRoutes.get()); } /** * Sets the new routes * @return old routes */ public Flux<Route> refresh() { return Flux.fromIterable(this.cachedRoutes.getAndUpdate( routes -> CachingRouteLocator.this.collectRoutes())); } private List<Route> collectRoutes() { List<Route> routes = this.delegate.getRoutes().collectList().block(); // 排序 AnnotationAwareOrderComparator.sort(routes); return routes; } @EventListener(RefreshRoutesEvent.class) /* for testing */ void handleRefresh() { refresh(); } }
org.springframework.context.ApplicationEvent.RefreshRoutesEvent 事件,刷新缓存。
GatewayWebfluxEndpoint 有一个 HTTP API 调用了 ApplicationEventPublisher ,发布 RefreshRoutesEvent 事件。代码以下 :code
@RestController @RequestMapping("${management.context-path:/application}/gateway") public class GatewayWebfluxEndpoint implements ApplicationEventPublisherAware { // ... 省略其余代码 /** * 应用事件发布器 */ private ApplicationEventPublisher publisher; @PostMapping("/refresh") public Mono<Void> refresh() { this.publisher.publishEvent(new RefreshRoutesEvent(this)); return Mono.empty(); } }
POST "/refresh ,发布 RefreshRoutesEvent 事件。CachingRouteLocator 监听到该事件,刷新缓存。