微服务网关Spring Cloud Gateway 之路由定义定位器
路由定义定位器
RouteDefinitionLocator
是路由定义定位器的顶级接口,具体的路由定义定位器都继承自该接口,其类图如下。
public interface RouteDefinitionLocator {
Flux<RouteDefinition> getRouteDefinitions();
}
可以看到定义了唯一一个方法,用以获取RouteDefinition
。RouteDefinition
对象作为属性定义在GatewayProperties
中,而网关的属性是可以直接在网关服务的配置文件中定义。下面我们看一下RouteDefinition
中是如何定义路由的。
public class RouteDefinition {
@NotEmpty
private String id = UUID.randomUUID().toString();
@NotEmpty
@Valid
private List<PredicateDefinition> predicates = new ArrayList<>();
@Valid
private List<FilterDefinition> filters = new ArrayList<>();
@NotNull
private URI uri;
private int order = 0;
}
在RouteDefinition
中,主要有五个属性:路由id、URI转发地址、order优先级、PredicateDefinition
路由断言定义和FilterDefinition
过滤器的定义。再深入的话,可以看到断言和过滤器属性是一个Map数据结构,用以存放多个对应的key-value数组。
通过RouteDefinitionLocator
的类图,可以看出该接口有四个实现类:
-
组合方式的CompositeRouteDefinitionLocator -
缓存方式的CachingRouteDefinitionLocator -
基于属性配置方式的PropertiesRouteDefinitionLocator -
基于服务发现的DiscoveryClientRouteDefinitionLocator。
在类图中,看到还有一个接口RouteDefinitionRepository
继承自RouteDefinitionLocator
,对路由定义进行操作,如保存和删除路由定义。下面我们分别介绍这几种路由定义定位器的实现。
路由定义的数据访问操作
RouteDefinitionRepository
接口中的方法用于对RouteDefinition
进行增、删、查操作。
public interface RouteDefinitionRepository extends RouteDefinitionLocator, RouteDefinitionWriter {
}
//RouteDefinitionWriter对路由定义进行操作
public interface RouteDefinitionWriter {
Mono<Void> save(Mono<RouteDefinition> route);
Mono<Void> delete(Mono<String> routeId);
}
该接口继承了RouteDefinitionWriter
,对路由定义进行操作。属于领域驱动设计(DDD)中的仓库,仓库封装了RouteDefinitionLocator
操作的方法,领域对象无须和底层数据库交互,它只需要从仓库中获取对象即可,在实现Spring Cloud Gateway内置的API端点时会用到这边的接口。InMemoryRouteDefinitionRepository
实现了RouteDefinitionRepository
接口,基于内存的路由定义仓库,也是唯一的实现类。当然我们可以根据需要自行扩展,存放在其他存储介质。
public class InMemoryRouteDefinitionRepository implements RouteDefinitionRepository {
// 定义了一个私有的线程安全的map,用来存储本地的RouteDefinition
private final Map<String, RouteDefinition> routes = synchronizedMap(new LinkedHashMap<String, RouteDefinition>());
@Override
public Mono<Void> save(Mono<RouteDefinition> route) {
// 保存一个路由定义,将路由定义保存到map中
return route.flatMap( r -> {
routes.put(r.getId(), r);
return Mono.empty();
});
}
@Override
public Mono<Void> delete(Mono<String> routeId) {
// 对路由定义操作,删除某个routeId的路由信息
return routeId.flatMap(id -> {
if (routes.containsKey(id)) {
routes.remove(id);
return Mono.empty();
}
return Mono.error(new NotFoundException("RouteDefinition not found: "+routeId));
});
}
@Override
public Flux<RouteDefinition> getRouteDefinitions() {
// 获取路由定义,遍历路由定义的map,并返回
return Flux.fromIterable(routes.values());
}
}
对路由定义操作的实现比较简单,这里定义了一个私有的线程安全的map,用来存储本地的RouteDefinition
。synchronizedMap
是Java集合中提供的静态方法,传入一个Map返回由特殊map支持的同步(线程安全)映射。实际上该方法只是一个工具方法,将传入Map的实现方法加一个同步(synchronized)锁代理,内部还是调用实现的对应方法。
- 点赞
- 收藏
- 关注作者
评论(0)