Spring-Cloud-Gateway之RouteDefinition初始化加載

RouteDefinition路由定義,Spring-Cloud-Gateway通過RouteDefinition來轉(zhuǎn)換生成具體的路由信息。RouteDefinition的信息是怎么加載初始化到網(wǎng)關(guān)系統(tǒng)中的,接下來閱讀Spring-Cloud-Gateway的RouteDefinitionLocator(路由定義信息加載器)接口,學(xué)習(xí)RouteDefinition初始化加載


首先查看RouteDefinitionLocator源碼

/**
 * 路由定義信息的定位器,
 * 負(fù)責(zé)讀取路由配置( org.springframework.cloud.gateway.route.RouteDefinition
 * 子類實(shí)現(xiàn)類
 *  1.CachingRouteDefinitionLocator -RouteDefinitionLocator包裝類, 緩存目標(biāo)RouteDefinitionLocator 為routeDefinitions提供緩存功能
 *  2.CompositeRouteDefinitionLocator -RouteDefinitionLocator包裝類,組合多種 RouteDefinitionLocator 的實(shí)現(xiàn),為 routeDefinitions提供統(tǒng)一入口
 *  3.PropertiesRouteDefinitionLocator-從配置文件(GatewayProperties 例如,YML / Properties 等 ) 讀取RouteDefinition
 *  4.DiscoveryClientRouteDefinitionLocator-從注冊中心( 例如,Eureka / Consul / Zookeeper / Etcd 等 )讀取RouteDefinition
 *  5.RouteDefinitionRepository-從存儲器( 例如,內(nèi)存 / Redis / MySQL 等 )讀取RouteDefinition
 * @author Spencer Gibb
 */
public interface RouteDefinitionLocator {

    /**
     * 獲取RouteDefinition
     * @return
     */
    Flux<RouteDefinition> getRouteDefinitions();
}

RouteDefinitionLocator接口有且僅有一個方法getRouteDefinitions,此方法獲取RouteDefinition的核心方法,返回Flux<RouteDefinition>


RouteDefinitionLocator 類圖如下:

graph TD
RouteDefinitionLocator-->CachingRouteDefinitionLocator
RouteDefinitionLocator-->CompositeRouteDefinitionLocator
RouteDefinitionLocator-->PropertiesRouteDefinitionLocator
RouteDefinitionLocator-->DiscoveryClientRouteDefinitionLocator
RouteDefinitionLocator-->RouteDefinitionRepository

子類功能描述:

  • CachingRouteDefinitionLocator:RouteDefinitionLocator包裝類, 緩存目標(biāo)RouteDefinitionLocator 為routeDefinitions提供緩存功能
  • CompositeRouteDefinitionLocator -RouteDefinitionLocator包裝類,組合多種 RouteDefinitionLocator 的實(shí)現(xiàn),為 routeDefinitions提供統(tǒng)一入口
  • PropertiesRouteDefinitionLocator-從配置文件(GatewayProperties 例如,YML / Properties 等 ) 讀取RouteDefinition
  • RouteDefinitionRepository-從存儲器( 例如,內(nèi)存 / Redis / MySQL 等 )讀取RouteDefinition
  • DiscoveryClientRouteDefinitionLocator-從注冊中心( 例如,Eureka / Consul / Zookeeper / Etcd 等

接下來詳細(xì)看子類的源碼分析主要實(shí)現(xiàn)功能

  • PropertiesRouteDefinitionLocator
/**
 * 從Properties(GatewayProperties)中加載RouteDefinition信息
 * @author Spencer Gibb
 */
public class PropertiesRouteDefinitionLocator implements RouteDefinitionLocator {

    /**
     * 從appliccation.yml中解析前綴為spring.cloud.gateway的配置
     */
    private final GatewayProperties properties;

    public PropertiesRouteDefinitionLocator(GatewayProperties properties) {
        this.properties = properties;
    }

    @Override
    public Flux<RouteDefinition> getRouteDefinitions() {
        return Flux.fromIterable(this.properties.getRoutes());
    }
}

PropertiesRouteDefinitionLocator很簡單從GatewayProperties實(shí)例獲取RouteDefinition信息

  • GatewayProperties 在GatewayProperties初始化加載文中已詳細(xì)描述
  • Flux 響應(yīng)式編程
  • CachingRouteDefinitionLocator
/**
 * RouteDefinitionLocator 包裝實(shí)現(xiàn)類,實(shí)現(xiàn)了路由定義的本地緩存功能
 * @author Spencer Gibb
 */
public class CachingRouteDefinitionLocator implements RouteDefinitionLocator {

    /**
     * 實(shí)際路由定義定位器
     */
    private final RouteDefinitionLocator delegate;
    
    private final Flux<RouteDefinition> routeDefinitions;
    /**
     * 路由定義的本地緩存
     */
    private final Map<String, List> cache = new HashMap<>();

    public CachingRouteDefinitionLocator(RouteDefinitionLocator delegate) {
        this.delegate = delegate;
        routeDefinitions = CacheFlux.lookup(cache, "routeDefs", RouteDefinition.class)
                .onCacheMissResume(() -> this.delegate.getRouteDefinitions());

    }

}   

RouteDefinitionLocator包裝類,緩存目標(biāo)RouteDefinitionLocator 為routeDefinitions提供緩存功能

  • DiscoveryClientRouteDefinitionLocator
public class DiscoveryClientRouteDefinitionLocator implements RouteDefinitionLocator {
    /**
     * 注冊中心客戶端
     */
    private final DiscoveryClient discoveryClient;
    /**
     * 本地配置信息
     */
    private final DiscoveryLocatorProperties properties;
    /**
     * 路由ID前綴
     */
    private final String routeIdPrefix;

    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() + "_";
        }
    }

    /**
     * 通過注冊中心查找服務(wù)組裝路由定義信息
     * @return
     */
    @Override
    public Flux<RouteDefinition> getRouteDefinitions() {
     ...代碼在根據(jù)注冊中心查找路由詳細(xì)解析

    }
}   

DiscoveryClientRouteDefinitionLocator通過調(diào)用 DiscoveryClient 獲取注冊在注冊中心的服務(wù)列表,生成對應(yīng)的 RouteDefinition 數(shù)組

  • CompositeRouteDefinitionLocator
/**
 * 組合多個 RouteDefinitionLocator 的實(shí)現(xiàn),為 routeDefinitions提供統(tǒng)一入口
 * @author Spencer Gibb
 */
public class CompositeRouteDefinitionLocator implements RouteDefinitionLocator {

    /**
     * 所有路由定義定位器實(shí)例集合
     */
    private final Flux<RouteDefinitionLocator> delegates;

    public CompositeRouteDefinitionLocator(Flux<RouteDefinitionLocator> delegates) {
        this.delegates = delegates;
    }

    @Override
    public Flux<RouteDefinition> getRouteDefinitions() {
        //將各個RouteDefinitionLocator的getRouteDefinitions合并返回統(tǒng)一的Flux<RouteDefinition>
        return this.delegates.flatMap(RouteDefinitionLocator::getRouteDefinitions);
    }
}

CompositeRouteDefinitionLocator 的主要作用就是將各個定位器合并提供統(tǒng)一的getRouteDefinitions方法入口

通過子類實(shí)現(xiàn)具體功能可以很清晰的看到定位器加載RouteDefinition整個流程

graph TD
PropertiesRouteDefinitionLocator-->|配置文件加載初始化| CompositeRouteDefinitionLocator
RouteDefinitionRepository-->|存儲器中加載初始化| CompositeRouteDefinitionLocator
DiscoveryClientRouteDefinitionLocator-->|注冊中心加載初始化| CompositeRouteDefinitionLocator

最終提供通過CompositeRouteDefinitionLocator提供統(tǒng)一的
getRouteDefinitions方法

RouteDefinitionLocator實(shí)例的初始化在GatewayAutoConfiguration中已經(jīng)完成

GatewayDiscoveryClientAutoConfiguration

@Configuration
@ConditionalOnProperty(name = "spring.cloud.gateway.enabled", matchIfMissing = true)
@AutoConfigureBefore(GatewayAutoConfiguration.class)
@ConditionalOnClass({DispatcherHandler.class, DiscoveryClient.class})
@EnableConfigurationProperties
public class GatewayDiscoveryClientAutoConfiguration {

    //初始化注冊中心路由定義定位器
    @Bean
    @ConditionalOnBean(DiscoveryClient.class)
    @ConditionalOnProperty(name = "spring.cloud.gateway.discovery.locator.enabled")
    public DiscoveryClientRouteDefinitionLocator discoveryClientRouteDefinitionLocator(
            DiscoveryClient discoveryClient, DiscoveryLocatorProperties properties) {
        return new DiscoveryClientRouteDefinitionLocator(discoveryClient, properties);
    }

GatewayAutoConfiguration

   //初始化配置路由定義加載器
    @Bean
    @ConditionalOnMissingBean
    public PropertiesRouteDefinitionLocator propertiesRouteDefinitionLocator(GatewayProperties properties) {
        return new PropertiesRouteDefinitionLocator(properties);
    }

    //初始化存儲路由定義加載器
    @Bean
    @ConditionalOnMissingBean(RouteDefinitionRepository.class)
    public InMemoryRouteDefinitionRepository inMemoryRouteDefinitionRepository() {
        return new InMemoryRouteDefinitionRepository();
    }

     //初始化聚合路由定義加載器
    @Bean
    @Primary
    public RouteDefinitionLocator routeDefinitionLocator(List<RouteDefinitionLocator> routeDefinitionLocators) {
        return new CompositeRouteDefinitionLocator(Flux.fromIterable(routeDefinitionLocators));
    }

在Spring-Cloud-Gateway初始化完成后需要的路由定義加載器已全部實(shí)例化完成,這樣就為路由的加載創(chuàng)建完成了必要的條件。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,506評論 19 139
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 47,254評論 6 342
  • Spring Web MVC Spring Web MVC 是包含在 Spring 框架中的 Web 框架,建立于...
    Hsinwong閱讀 22,931評論 1 92
  • 前言 在微服務(wù)架構(gòu)的系統(tǒng)中,我們通常會使用輕量級的消息代理來構(gòu)建一個共用的消息主題讓系統(tǒng)中所有微服務(wù)實(shí)例都連接上來...
    Chandler_玨瑜閱讀 6,764評論 2 39
  • 有多久沒想過動手寫點(diǎn)什么了呢? 這個世界,總有一些人走在人群前端,他們無所畏懼四處闖蕩,給人類歷史上留下一串串醒目...
    不二小茹閱讀 288評論 0 0

友情鏈接更多精彩內(nèi)容