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

细心的读者可能会发现,在第四篇文章中的createService方法中,并没有把所有的服务实例化,下面这些服务,只是记了他们的类型:
src\vs\code\electron-main\main.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负责记录这些服务的类型,以供后续使用
(src\vs\platform\instantiation\common\descriptors.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方法如下:(src\vs\platform\instantiation\common\instantiationService.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负责创建对象的实例(暂时先不解释)
下次获取这个对象的时候,就直接从缓存中获取了

vscode源码分析【六】服务实例化和单例的实现的更多相关文章

  1. vscode源码分析【七】主进程启动消息通信服务

    第一篇: vscode源码分析[一]从源码运行vscode 第二篇:vscode源码分析[二]程序的启动逻辑,第一个窗口是如何创建的 第三篇:vscode源码分析[三]程序的启动逻辑,性能问题的追踪 ...

  2. vscode源码分析【四】程序启动的逻辑,最初创建的服务

    第一篇: vscode源码分析[一]从源码运行vscode 第二篇:vscode源码分析[二]程序的启动逻辑,第一个窗口是如何创建的 第三篇:vscode源码分析[三]程序的启动逻辑,性能问题的追踪 ...

  3. vscode源码分析【九】窗口里的主要元素

    第一篇: vscode源码分析[一]从源码运行vscode 第二篇:vscode源码分析[二]程序的启动逻辑,第一个窗口是如何创建的 第三篇:vscode源码分析[三]程序的启动逻辑,性能问题的追踪 ...

  4. vscode源码分析【八】加载第一个画面

    第一篇: vscode源码分析[一]从源码运行vscode 第二篇:vscode源码分析[二]程序的启动逻辑,第一个窗口是如何创建的 第三篇:vscode源码分析[三]程序的启动逻辑,性能问题的追踪 ...

  5. vscode源码分析【五】事件分发机制

    第一篇: vscode源码分析[一]从源码运行vscode 第二篇:vscode源码分析[二]程序的启动逻辑,第一个窗口是如何创建的 第三篇:vscode源码分析[三]程序的启动逻辑,性能问题的追踪 ...

  6. zookeeper源码分析之五服务端(集群leader)处理请求流程

    leader的实现类为LeaderZooKeeperServer,它间接继承自标准ZookeeperServer.它规定了请求到达leader时需要经历的路径: PrepRequestProcesso ...

  7. zookeeper源码分析之四服务端(单机)处理请求流程

    上文: zookeeper源码分析之一服务端启动过程 中,我们介绍了zookeeper服务器的启动过程,其中单机是ZookeeperServer启动,集群使用QuorumPeer启动,那么这次我们分析 ...

  8. vscode源码分析【三】程序的启动逻辑,性能问题的追踪

    第一篇: vscode源码分析[一]从源码运行vscode 第二篇:vscode源码分析[二]程序的启动逻辑,第一个窗口是如何创建的 启动追踪 代码文件:src\main.js 如果指定了特定的启动参 ...

  9. Spring Ioc源码分析系列--Bean实例化过程(一)

    Spring Ioc源码分析系列--Bean实例化过程(一) 前言 上一篇文章Spring Ioc源码分析系列--Ioc容器注册BeanPostProcessor后置处理器以及事件消息处理已经完成了对 ...

随机推荐

  1. Android框架式编程之ViewModel

    一.ViewModel介绍 ViewModel类是被设计用来以可感知生命周期的方式存储和管理 UI 相关数据.ViewModel中数据会一直存活即使 Activity Configuration发生变 ...

  2. Linux发行版的系统目录名称命名规则以及用途

    linux各种发行版都遵循LSB(Linux Stadards Base)规则,使用一致的相关的基础目录名称,使用根目录系统结构(root filesystem),使用FHS(Files Hierar ...

  3. Nginx 简介与安装、常用的命令和配置文件

    1.nginx 简介(1)介绍 nginx 的应用场景和具体可以做什么事情 (2)介绍什么是反向代理 (3)介绍什么是负载均衡 (4)介绍什么是动静分离 2.nginx 安装(1)介绍 nginx 在 ...

  4. 《Web Development with Go》JWT认证

    时间晚了,先来一版调通的JWT普通认证, 明天再弄一个通过中间件,及gorilla,negroni库的认证, 这样正规些, 但认证通过之后,如何对应权限? 由于jwt-go从2升到3,还有rsa 10 ...

  5. 新入手的Mac,该如何设置?

    如果您入手了一台Mac.设置Mac的过程直观且易于执行,但是如果您是新手,可能会遇到有一些小麻烦.没关系,本篇文章小编将帮助您设置Mac,让您像专业人士一样迅速运转您的Mac. 设置前提 在开始设置全 ...

  6. [CodeForces-1225A] Forgetting Things 【构造】

    [CodeForces-1225A] Forgetting Things [构造] 标签: 题解 codeforces题解 构造 题目描述 Time limit 2000 ms Memory limi ...

  7. CSharpGL(56)[译]Vulkan入门

    CSharpGL(56)[译]Vulkan入门 本文是对(http://ogldev.atspace.co.uk/www/tutorial50/tutorial50.html)的翻译,作为学习Vulk ...

  8. Run-Time Check Failure #2 - Stack around the variable 's' was corrupted. 出现了 。

    程序中存在内存越界,注意数组大小和数据大小.

  9. Java题库——Chapter12 异常处理和文本IO

    异常处理 1)What is displayed on the console when running the following program? class Test { public stat ...

  10. Vim 宏实战操作

    宏的概念 什么是宏呢?英文名:macro,代表一串命令的集合. 示例操作文本 SELECT * FROM `edu_ocr_task` WHERE ((`userId`=284871) AND (`u ...