一、入口
获取app的信息的方法是在DiscoveryClientRouteDefinitionLocator类型的getRouteDefinitions()方法中:
return Flux.fromIterable(discoveryClient.getServices())
.map(discoveryClient::getInstances)
.filter(instances -> !instances.isEmpty())
.map(instances -> instances.get(0))
.filter(instance -> {
Boolean include = includeExpr.getValue(evalCtxt, instance, Boolean.class);
if (include == null) {
return false;
}
return include;
上面的信息是从discoveryClient属性中获取到的,这个discoveryClient是DiscoveryClientRouteDefinitionLocator类中的一个属性:
二、discoveryClient
关于discoveryClient存储了spring cloud gateway的初始节点services,那么这个节点是怎么读入进来的呢,如下
1、首先discoryClient是在DiscoveryClientRouteDefinitionLocator的构造方法中初始化:
public DiscoveryClientRouteDefinitionLocator(DiscoveryClient discoveryClient, DiscoveryLocatorProperties properties) {
this.discoveryClient = discoveryClient;
this.properties = properties;
if (StringUtils.hasText(properties.getRouteIdPrefix())) {
this.routeIdPrefix = properties.getRouteIdPrefix();
} else {
this.routeIdPrefix = this.discoveryClient.getClass().getSimpleName() + "_";
}
}
2、DiscoveryClientRouteDefinitionLocator是一个bean:
@Bean
@ConditionalOnBean(DiscoveryClient.class)
@ConditionalOnProperty(name = "spring.cloud.gateway.discovery.locator.enabled")
public DiscoveryClientRouteDefinitionLocator discoveryClientRouteDefinitionLocator(
DiscoveryClient discoveryClient, DiscoveryLocatorProperties properties) {
return new DiscoveryClientRouteDefinitionLocator(discoveryClient, properties);
}
3、其中DiscoveryClient的类型是CompositeDiscoveryClient
@Bean
@Primary
public CompositeDiscoveryClient compositeDiscoveryClient(List<DiscoveryClient> discoveryClients) {
return new CompositeDiscoveryClient(discoveryClients);
}
4、其中参数是DiscoveryClient类型的List,ZookeeperDiscoveryClient是其子类:
@Bean
@ConditionalOnMissingBean
// currently means auto-registration is false. That will change when ZookeeperServiceDiscovery is gone
public ZookeeperDiscoveryClient zookeeperDiscoveryClient(ServiceDiscovery<ZookeeperInstance> serviceDiscovery) {
return new ZookeeperDiscoveryClient(serviceDiscovery, this.zookeeperDependencies);
}
5、入参是ServiceDiscovery类型的bean
public ServiceDiscovery<T> build()
{
if ( serializer == null )
{
serializer(new JsonInstanceSerializer<T>(payloadClass));
}
return new ServiceDiscoveryImpl<T>(client, basePath, serializer, thisInstance, watchInstances);
}
6、这个bean是通过ServiceDiscoveryBuilder构造的,basePath参数就是我们使用到的services。basePath的设置是在DefaultServiceDiscoveryCustomizer的customize()方法中
@Override
public ServiceDiscovery<ZookeeperInstance> customize(ServiceDiscoveryBuilder<ZookeeperInstance> builder) {
// @formatter:off
return builder
.client(this.curator)
.basePath(this.properties.getRoot())
.serializer(this.instanceSerializer)
.build();
// @formatter:on
}
7、DefaultServiceDiscoveryCustomizer 此bean的创建方法如下
@Bean
@ConditionalOnMissingBean(ServiceDiscoveryCustomizer.class)
public DefaultServiceDiscoveryCustomizer defaultServiceDiscoveryCustomizer(
CuratorFramework curator, ZookeeperDiscoveryProperties properties,
InstanceSerializer<ZookeeperInstance> serializer) {
return new DefaultServiceDiscoveryCustomizer(curator, properties, serializer);
}
8、入参properties类型是ZookeeperDiscoveryProperties类型,root值如下:】
private String root = "/services";
至此,就可以看出spring cloud gateway的根目录是/services。