zoukankan      html  css  js  c++  java
  • vscode源码分析【六】服务实例化和单例的实现

    第一篇: vscode源码分析【一】从源码运行vscode
    第二篇:vscode源码分析【二】程序的启动逻辑,第一个窗口是如何创建的
    第三篇:vscode源码分析【三】程序的启动逻辑,性能问题的追踪
    第四篇:vscode源码分析【四】程序启动的逻辑,最初创建的服务
    第五篇:vscode源码分析【五】事件分发机制

    细心的读者可能会发现,在第四篇文章中的createService方法中,并没有把所有的服务实例化,下面这些服务,只是记了他们的类型:
    srcvscodeelectron-mainmain.ts

    		services.set(ILifecycleService, new SyncDescriptor(LifecycleService));
    		services.set(IStateService, new SyncDescriptor(StateService));
    		services.set(IRequestService, new SyncDescriptor(RequestService));
    		services.set(IDiagnosticsService, new SyncDescriptor(DiagnosticsService));
    		services.set(IThemeMainService, new SyncDescriptor(ThemeMainService));
    		services.set(ISignService, new SyncDescriptor(SignService));

    SyncDescriptor负责记录这些服务的类型,以供后续使用
    (srcvsplatforminstantiationcommondescriptors.ts)

    export class SyncDescriptor<T> {
    	readonly ctor: any;
    	readonly staticArguments: any[];
    	readonly supportsDelayedInstantiation: boolean;
    	constructor(ctor: new (...args: any[]) => T, staticArguments: any[] = [], supportsDelayedInstantiation: boolean = false) {
    		this.ctor = ctor;
    		this.staticArguments = staticArguments;
    		this.supportsDelayedInstantiation = supportsDelayedInstantiation;
    	}
    }

    接下来,main.ts的startup方法内,就实例化了这些服务

    			await instantiationService.invokeFunction(async accessor => {
    				const environmentService = accessor.get(IEnvironmentService);
    				const configurationService = accessor.get(IConfigurationService);
    				const stateService = accessor.get(IStateService);
    				try {
    					await this.initServices(environmentService, configurationService as ConfigurationService, stateService as StateService);
    				} catch (error) {
    
    					// Show a dialog for errors that can be resolved by the user
    					this.handleStartupDataDirError(environmentService, error);
    
    					throw error;
    				}
    			});

    这里accessor的get方法如下:(srcvsplatforminstantiationcommoninstantiationService.ts)

    				get: <T>(id: ServiceIdentifier<T>, isOptional?: typeof optional) => {
    
    					if (_done) {
    						throw illegalState('service accessor is only valid during the invocation of its target method');
    					}
    
    					const result = this._getOrCreateServiceInstance(id, _trace);
    					if (!result && isOptional !== optional) {
    						throw new Error(`[invokeFunction] unknown service '${id}'`);
    					}
    					return result;
    				}

    有个_getOrCreateServiceInstance方法:

    	private _getOrCreateServiceInstance<T>(id: ServiceIdentifier<T>, _trace: Trace): T {
    		let thing = this._getServiceInstanceOrDescriptor(id);
    		if (thing instanceof SyncDescriptor) {
    			return this._createAndCacheServiceInstance(id, thing, _trace.branch(id, true));
    		} else {
    			_trace.branch(id, false);
    			return thing;
    		}
    	}

    你发现,如果它想获取的对象是SyncDescriptor类型的,就会创建并缓存相应的对象
    这个方法_createAndCacheServiceInstance负责创建对象的实例(暂时先不解释)
    下次获取这个对象的时候,就直接从缓存中获取了
     

  • 相关阅读:
    java将汉语转换为拼音工具类
    Maven 参数说明
    tcp socket的backlog参数
    Java 运行中jar包冲突,定位使用哪个jar包
    Java CMS GC
    数据仓库
    compareTo
    java程序性能分析之thread dump和heap dump
    npm 与 package.json 快速入门教程
    基本 Java Bean
  • 原文地址:https://www.cnblogs.com/liulun/p/11049921.html
Copyright © 2011-2022 走看看