1. 程式人生 > 其它 >Soul閘道器原始碼學習06

Soul閘道器原始碼學習06

技術標籤:souljava

Soul閘道器原始碼學習06

文章目錄

Soul外掛

在soul閘道器中每個請求,都會通過責任鏈的方式執行相匹配的外掛,所以外掛也是soul閘道器的核心,soul閘道器的外掛是可插拔的,並且是外掛之間依賴關係是鬆耦合且外掛的功能實現高聚合,其次使用者可根據需求定製外掛滿足自己的需求。

SoulConfiguration

soul外掛配置類,使用 spring.factories 載入該配置。

@Bean("webHandler"
) public SoulWebHandler soulWebHandler(final ObjectProvider<List<SoulPlugin>> plugins) { List<SoulPlugin> pluginList = plugins.getIfAvailable(Collections::emptyList); //對所有外掛進行排序 final List<SoulPlugin> soulPlugins = pluginList.stream() .sorted(Comparator.
comparingInt(SoulPlugin::getOrder)).collect(Collectors.toList()); //輸出所有載入的外掛 soulPlugins.forEach(soulPlugin -> log.info("load plugin:[{}] [{}]", soulPlugin.named(), soulPlugin.getClass().getName())); return new SoulWebHandler(soulPlugins); }

1、ObjectProvider 使用更寬鬆的方式注入SoulPlugin。

2、對所有外掛進行排序,輸出所有載入的外掛。
3、建立SoulWebHandler對接,構造方法傳遞所有外掛。

SoulPlugin

所有的外掛實現SoulPlugin類,並重寫對應的方法。

//執行外掛
Mono<Void> execute(ServerWebExchange exchange, SoulPluginChain chain);
//排序
int getOrder();
//外掛名
default String named() {
    return "";
}
//是否終止
default Boolean skip(ServerWebExchange exchange) {
    return false;
}

//Hystrix 外掛配置
@Bean
public SoulPlugin hystrixPlugin() {
return new HystrixPlugin();
}
//WebSocket外掛配置
@Bean
public SoulPlugin webSocketPlugin(WebSocketClient webSocketClient, WebSocketService webSocketService) {
return new WebSocketPlugin(webSocketClient, webSocketService);
}
//dubbo外掛
@Bean
public SoulPlugin apacheDubboPlugin(ObjectProvider<DubboParamResolveService> dubboParamResolveService) {
    return new ApacheDubboPlugin(new ApacheDubboProxyService(dubboParamResolveService.getIfAvailable()));
}

SoulWebHandler

執行外掛通過責任鏈的方式。

@Override
public Mono<Void> handle(@NonNull final ServerWebExchange exchange) {
    MetricsTrackerFacade.getInstance().counterInc(MetricsLabelEnum.REQUEST_TOTAL.getName());
    Optional<HistogramMetricsTrackerDelegate> startTimer = 	MetricsTrackerFacade.getInstance().histogramStartTimer(MetricsLabelEnum.REQUEST_LATENCY.getName());
    //責任鏈呼叫外掛
    return new DefaultSoulPluginChain(plugins).execute(exchange).subscribeOn(scheduler).doOnSuccess(t -> startTimer.ifPresent(time -> MetricsTrackerFacade.getInstance().histogramObserveDuration(time)));
}

public Mono<Void> execute(final ServerWebExchange exchange) {
    return Mono.defer(() -> {
        if (this.index < plugins.size()) {
            //從集合中獲取當前外掛
            SoulPlugin plugin = plugins.get(this.index++);
            Boolean skip = plugin.skip(exchange);
            //判斷是否中斷本次執行
            if (skip) {
                return this.execute(exchange);
            }
            return plugin.execute(exchange, this);
        }
        return Mono.empty();
    });
}