Soul閘道器原始碼學習06
阿新 • • 發佈:2021-01-21
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。
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();
});
}