详解Angular 4.x Injector

网友投稿 248 2023-05-19


详解Angular 4.x Injector

在介绍 Angular Injector (注入器) 之前,我们先要了解 Dependency Injection,即依赖注入的概念。

依赖注入允许程序设计遵从依赖倒置原则 (简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户端与实现模块间的耦合) 调用者只需知道服务的接口,具体服务的查找和创建由注入器 (Injector) 负责处理并提供给调用者,这样就分离了服务和调用者的依赖,符合低耦合的程序设计原则。

从上述的内容可知,依赖注入中包含三种角色:调用者、服务和注入器 (Injector)。现在我们开始介绍 Injector,在 Angular 中 Injector (注入器) 用来管理服务对象的创建和获取。接下来我们先来看一下 Injector 抽象类:

Injector 抽象类

// angular2\packages\core\src\di\injector.ts

export abstract class Injector {

static THROW_IF_NOT_FOUND = _THROW_IF_NOT_FOUND;

static NULL: Injector = new _NullInjector();

/**

* 用于根据给定的Token从注入器中获取相应的对象。

* 如果没有找到相应的对象,将返回notFoundValue设置的值。若notFoundValue的值与

* _THROW_IF_NOT_FOUND相等,则会抛出异常。

*/

abstract get(token: Type|InjectionToken, notFoundValue?: T): T;

}

const _THROW_IF_NOT_FOUND = new Object();

Injector 抽象类中定义了一个 get() 抽象方法,该方法用于根据给定的 Token 从注入器中获取相应的对象,每个Injector 抽象类的子类都必须实现该方法。在 Angular 中常见的 Injector 抽象类子类有:

_NullInjector

ReflectiveInjector

下面我们来依次介绍它们:

_NullInjector 类

_NullInjector 类的实例用于表示空的注入器。

// angular2\packages\core\src\di\injector.ts

class _NullInjector implements Injector {

get(token: any, notFoundValue: any = _THROW_IF_NOT_FOUND): any {

if (notFoundValue === _THROW_IF_NOT_FOUND) {

throw new Error(`No provider for ${stringify(token)}!`);

}

return notFoundValue;

}

}

ReflectiveInjector 抽象类

ReflectiveInjector 表示一个依赖注入容器,用于实例化对象和sZsORRuz解析依赖。

ReflectiveInjector 使用示例

@Injectable()

class Engine {}

@Injectable()

class Car {

constructor(public engine:Engine) {}

}

var injector = ReflectiveInjector.resolveAndCreate([Car, Engine]);

var car = injector.get(Car);

expect(car instanceof Car).toBe(true);

expect(car.engine instanceof Engine).toBe(true);

上面示例中,我们通过调用 ReflectiveInjector 抽象类的 resolveAndCreate() 方法,创建注入器。然后通过调用注入器的 get() 方法,获取 Token 对应的对象。该抽象类除了 resolveAndCreate() 静态方法外,还含有以下静态方法:

resolve() - 解析 Provider 列表为 ResolvedReflectiveProvider 列表

fromResolvedProviders() - 基于 ResolvedReflectiveProvider 列表创建 ReflectiveInjector 对象

接下来我们来分析上述的静态方法:

resolveAndCreate()

static resolveAndCreate(providers: Provider[], parent?: Injector): ReflectiveInjector {

const ResolvedReflectiveProviders = ReflectiveInjector.resolve(providers);

return ReflectiveInjector.fromResolvedProviders(ResolvedReflectiveProviders, parent);

}

从上面代码中,我们可以看出 resolveAndCreate() 方法内部是通过调用 ReflectiveInjector.resolve() 方法和 ReflectiveInjector.fromResolvedProviders() 方法来创建 ReflectiveInjector 对象。

resolve()

该方法用于把 Provider 数组解析为 ResolvedReflectiveProvider 数组。

static resolve(providers: Provider[]): ResolvedReflectiveProvider[] {

return resolveReflectiveProviders(providers);

}

resolve() 使用示例

@Injectable()

class Engine {}

@Injectable()

class Car {

constructor(public engine:Engine) {}

}

var providers = ReflectiveInjector.resolve([Car, [[Engine]]]);

expect(providers.length).toEqual(2);

expect(providers[0] instanceof ResolvedReflectiveProvider).toBe(true);

expect(providers[0].key.displayName).toBe("Car");

expect(providers[1].key.displayName).toBe("Engine");

resolve() 解析图示

Provider 类型

export type Provider =

TypeProvider | ValueProvider | ClassProvider | ExistingProvider | FactoryProvider | any[];

// ApiService

export interface TypeProvider extends Type {}

// { provide: ApiService, useClass: ApiService }

export interface ClassProvider {

// 用于设置与依赖对象关联的Token值,Token值可能是Type、InjectionToken、OpaqueToken的实例或字符串

provide: any;

useClass: Type;

// 用于标识是否multiple providers,若是multiple类型,则返回与Token关联的依赖对象列表

multi?: boolean;

}

// { provide: 'API_URL', useValue: 'http://my.api.com/v1' }

export interface ValueProvider {

provide: any;

useValue: any;

multi?: boolean;

}

// { provide: 'ApiServiceAlias', useExisting: ApiService }

export interface ExistingProvider {

provide: any;

useExisting: any;

multi?: boolean;

}

// { provide: APP_INITIALIZER, useFactory: configFactory, deps: [AppConfig], multi: true }

export interface FactoryProvider {

provide: any;

useFactory: Function;

deps?: any[]; // 用于设置工厂函数的依赖对象

multi?: boolean;

}

ResolvedReflectiveProvider 接口

export interface ResolvedReflectiveProvider {

// 唯一的对象用来从ReflectiveInjector中获取对象

key: ReflectiveKey;

// 工厂函数用于创建key相关的依赖对象

resolvedFactories: ResolvedReflectiveFactory[];

// 标识当前的provider是否为multi-provider

multiProvider: boolean;

}

ResolvedReflectiveFactory 类

export class ResolvedReflectiveFactory {

constructor(

public factory: Function,

public dependencies: ReflectiveDependency[]) {}

}

ReflectiveDependency 类

export class ReflectiveDependency {

constructor(

public key: ReflectiveKey,

public optional: boolean,

public visibility: Self|SkipSelf|null) {}

static fromKey(key: ReflectiveKey): ReflectiveDependency {

return new ReflectiveDependency(key, false, null);

}

}

ReflectiveKey 类

ReflectiveKey 对象中包含两个属性:系统范围内唯一的id 和 token。系统范围内唯一的id,允许注入器以更高效的方式存储已创建的对象。另外我们不能手动的创建 ReflectiveKey,当 ReflectiveInjector 对象解析 providers 的时候会自动创建 ReflectiveKey 对象。

export class ReflectiveKey {

constructor(public token: Object, public id: number) {

if (!token) {

throw new Error('Token must be defined!');

}

}

// 返回序列化的token

get displayName(): string { return stringify(this.token); }

// 获取token对应的ReflectiveKey

static get(token: Object): ReflectiveKey {

return _globalKeyRegistry.get(resolveForwardRef(token));

}

// 获取系统中已注册ReflectiveKey的个数

static get numberOfKeys(): number { return _globalKeyRegistry.numberOfKeys; }

}

const _globalKeyRegistry = new KeyRegistry(); // 创建Key仓库

export class KeyRegistry {

private _allKeys = new Map();

/**

* 若token是ReflectiveKey类的实例,则直接返回。若_allKeys对象中包含token属性

* 则返回token对应的ReflectiveKey对象。否则创建一个新的ReflectiveKey对象,并

* 保存到_allKeys对象中

*/

get(token: Object): ReflectiveKey {

if (token instanceof ReflectiveKey) return token;

if (this._allKeys.has(token)) {

return this._allKeys.get(token) !;

}

const newKey = new ReflectiveKey(token, ReflectiveKey.numberOfKeys);

this._allKeys.set(token, newKey);

return newKey;

}

// 获取已保存ReflectiveKey的个数

get numberOfKeys(): number { return this._allKeys.size; }

}

分析完 resolve() 方法的输入参数和返回类型,我们来看一下该方法内部的具体实现:

export function resolveReflectiveProviders(providers: Provider[])

: ResolvedReflectiveProvider[] {

const normalized = _normalizeProviders(providers, []); // 步骤一

const resolved = normalized.map(resolveReflectiveProvider); // 步骤二

const resolvedProviderMap = mergeResolvedReflectiveProviders(resolved, new Map()); // 步骤三

return Array.from(resolvedProviderMap.values()); // 步骤四

}

步骤一 —— 规范化Provider

const normalized = _normalizeProviders(providers, []);

// 规范化Providers

function _normalizeProviders(providers: Provider[], res: Provider[]): Provider[] {

providers.forEach(b => {

// providers: [Type] => providers: [{provide: Type, useClass: Type }]

if (b instanceof Type) {

res.push({provide: b, useClass: b});

} else if (b && typeof b == 'object' && (b as any).provide !== undefined) {

res.push(b as NormalizedProvider);

} else if (b instanceof Array) { // 若b是数组,则递归调用_normalizeProviders()方法

_normalizeProviders(b, res);

} else {

throw invalidProviderError(b);

}

});

return res;

}

interface NormalizedProvider extends TypeProvider, ValueProvider, ClassProvider,

ExistingProvider, FactoryProvider {}

步骤二 —— 转化NormalizedProvider为ResolvedReflectiveProvider

const resolved = normalized.map(resolveReflectiveProvider);

// 解析NormalizedProvider为ResolvedReflectiveProvider

function resolveReflectiveProvider(provider: NormalizedProvider): ResolvedReflectiveProvider {

return new ResolvedReflectiveProvider_(

ReflectiveKey.get(provider.provide), [resolveReflectiveFactory(provider)],

provider.multi || false);

}

// 用于创建已解析的Provider实例

export class ResolvedReflectiveProvider_ implements ResolvedReflectiveProvider {

constructor(

public key: ReflectiveKey,

public resolvedFactories: ResolvedReflectiveFactory[],

public multiProvider: boolean) {}

get resolvedFactory(): ResolvedReflectiveFactory { return this.resolvedFactories[0]; }

}

// 解析NormalizedProvider对象,创建ResolvedReflectiveFactory对象

function resolveReflectiveFactory(provider: NormalizedProvider): ResolvedReflectiveFactory {

let factoryFn: Function;

let resolvedDeps: ReflectiveDependency[];

if (provider.useClass) {

// { provide: ApiService, useClass: ApiService }

const useClass = resolveForwardRef(provider.useClass);

factoryFn = reflector.factory(useClass);

resolvedDeps = _dependenciesFor(useClass);

} else if (provider.useExisting) {

// { provide: 'ApiServiceAlias', useExisting: ApiService }

factoryFn = (aliasInstance: any) => aliasInstance;

resolvedDeps = [ReflectiveDependency.fromKey(ReflectiveKey.get(provider.useExisting))];

} else if (provider.useFactory) {

// { provide: APP_INITIALIZER, useFactory: configFactory, deps: [AppConfig],

// multi: true }

factoryFn = provider.useFactory;

resolvedDeps = constructDependencies(provider.useFactory, provider.deps);

} else {

// { provide: 'API_URL', useValue: 'http://my.api.com/v1' }

factoryFn = () => provider.useValue;

// const _EMPTY_LIST: any[] = [];

resolvedDeps = _EMPTY_LIST;

}

return new ResolvedReflectiveFactory(factoryFn, resolvedDeps);

}

步骤三 —— 合并已解析的Provider

const resolvedProviderMap = mergeResolvedReflectiveProviders(resolved, new Map());

export function mergeResolvedReflectiveProviders(

providers: ResolvedReflectiveProvider[],

normalizedProvidersMap: Map):

Map {

for (let i = 0; i < providers.length; i++) {

const provider = providers[i];

// 从normalizedProvidersMap对象中获取key.id对应的ResolvedReflectiveProvider对象

const existing = normalizedProvidersMap.get(provider.key.id);

if (existing) {

// 如果当前的provider不是multi provider,则抛出异常

if (provider.multiProvider !== existing.multiProvider) {

throw mixingMultiProvidersWithRegularProvidersError(existing, provider);

}

// 如果当前的provider是multi provider,则把当前provider的resolvedFactories

// 列表中的每一项添加到已存在的provider对象的resolvedFactories列表中。

if (provider.multiProvider) {

for (let j = 0; j < provider.resolvedFactories.length; j++) {

existing.resolvedFactories.push(provider.resolvedFactories[j]);

}

} else {

// 如果当前的provider不是multi provider,则覆盖已存在的provider

normalizedProvidersMap.set(provider.key.id, provider);

}

} else {

let resolvedProvider: ResolvedReflectiveProvider;

// 如果当前的provider是multi provider,则创建一个新的ResolvedReflectiveProvider对象

if (provider.multiProvider) {

resolvedProvider = new ResolvedReflectiveProvider_(

provider.key, provider.resolvedFactories.slice(), provider.multiProvider);

} else {

resolvedProvider = provider;

}

// 在normalizedProvidersMap中保存已解析的ResolvedReflectiveProvider对象

normalizedProvidersMap.set(provider.key.id, resolvedProvider);

}

}

return normalizedProvidersMap;

}

步骤四 —— 生成ResolvedReflectiveProvider[]

// resolvedProviderMap的values,创建ResolvedReflectiveProvider[]

Array.from(resolvedProviderMap.values());

/**

* 基于一个类似数组或可迭代对象创建一个新的数组实例

*

* arrayLike:转换成真实数组的类数组对象或可遍历对象。

* mapFn(可选):如果指定了该参数,则最后生成的数组会经过该函数的加工处理后再返回。

* thisArg(可选):执行mapFn函数时this的值。

*/

Array.from(arrayLike[, mapFn[, thisArg]])

fromResolvedProviders()

该方法用于基于已解析的 providers 创建注入器。

static fromResolvedProviders(providers: ResolvedReflectiveProvider[], parent?: Injector):

ReflectiveInjector {

return new ReflectiveInjector_(providers, parent);

}

fromResolvedProviders() 使用示例

@Injectable()

class Engine {}

@Injectable()

class Car {

constructor(public engine:Engine) {}

}

var providers = ReflectiveInjector.resolve([Car, Engine]);

var injector = ReflectiveInjector.fromResolvedProviders(providers);

expect(injector.get(Car) instanceof Car).toBe(true);

了解完 fromResolvedProviders() 方法的使用方式,接下来我们来重点分析一下 ReflectiveInjector_ 类。

ReflectiveInjector_ 类

ReflectiveInjector_ 类的属性

// 构造次数

_constructionCounter: number = 0;

// ResolvedReflectiveProvider列表

public _providers: ResolvedReflectiveProvider[];

// 父级注入器

public _parent: Injector|null;

// ReflectiveKey id列表

keyIds: number[];

// 依赖对象列表

objs: any[];

ReflectiveInjector_ 构造函数

export class ReflectiveInjector_ implements ReflectiveInjector {

constructor(_providers: ResolvedReflectiveProvider[], _parent?: Injector) {

this._providers = _providers;

// 设置父级注入器

this._parent = _parent || null;

const len = _providers.length;

this.keyIds = new Array(len);

this.objs = new Array(len);

// 初始化keyIds列表和objs对象列表

for (let i = 0; i < len; i++) {

this.keyIds[i] = _providers[i].key.id;

this.objs[i] = UNDEFINED;

}

}

}

const UNDEFINED = new Object();

ReflectiveInjector_ 类的方法

ReflectiveInjector_ 类中的方法较多,我们只分析其中比较重要的方法,首先先根据方法的实现的功能进行分类:

用于创建ReflectiveInjector注入器

用于获取对象

用于创建对象

用于获取工厂函数依赖对象

用于创建ReflectiveInjector注入器

// 基于Provider列表并创建子注入器

resolveAndCreateChild(providers: Provider[]): ReflectiveInjector {

const ResolvedReflectiveProviders = ReflectiveInjector.resolve(providers);

return this.createChildFromResolved(ResolvedReflectiveProviders);

}

// 基于已解析的ResolvedReflectiveProvider列表,创建子注入器

createChildFromResolved(providers: ResolvedReflectiveProvider[]): ReflectiveInjector {

const inj = new ReflectiveInjector_(providers);

inj._parent = this;

return inj;

}

用于获取对象

// 获取当前注入器的父级注入器

get parent(): Injector|null { return this._parent; }

// 获取token对应的依赖对象

get(token: any, notFoundValue: any = THROW_IF_NOT_FOUND): any {

return this._getByKey(ReflectiveKey.get(token), null, notFoundValue);

}

// 根据ReflectiveKey及visibility可见性,获取对应的依赖对象

private _getByKey(key: ReflectiveKey, visibility: Self|SkipSelf|null, notFoundValue: any): any {

// const INJECTOR_KEY = ReflectiveKey.get(Injector);

if (key === INJECTOR_KEY) {

return this;

}

// 判断该依赖对象是否使用@Self装饰器定义,表示从本级注入器获取依赖对象

if (visibility instanceof Self) {

return this._getByKeySelf(key, notFoundValue);

} else {

// 使用默认的方式获取依赖对象

return this._getByKeyDefault(key, notFoundValue, visibility);

}

}

// 从本级注入器获取依赖对象

_getByKeySelf(key: ReflectiveKey, notFoundValue: any): any {

const obj = this._getObjByKeyId(key.id);

return (obj !== UNDEFINED) ? obj : this._throwOrNull(key, notFoundValue);

}

// 使用默认的方式获取依赖对象

_getByKeyDefault(key: ReflectiveKey, notFoundValue: any,

visibility: Self|SkipSelf|null): any {

let inj: Injector|null;

// 判断该依赖对象是否使用@SkipSelf装饰器定义,表示不从本级注入器获取依赖对象

if (visibility instanceof SkipSelf) {

inj = this._parent;

} else {

inj = this;

}

// 从本级注入器获取依赖对象,若本级获取不到,则从父级注入器中查找

while (inj instanceof ReflectiveInjector_) {

const inj_ = inj;

const obj = inj_._getObjByKeyId(key.id);

if (obj !== UNDEFINED) return obj;

inj = inj_._parent;

}

if (inj !== null) {

return inj.get(key.token, notFoundValue);

} else {

return this._throwOrNull(key, notFoundValue);

}

}

// 获取keyId对应的对象,如依赖对象未创建,则调用_new()方法创建一个,然后保存到

// this.objs对象列表中

private _getObjByKeyId(keyId: number): any {

for (let i = 0; i < this.keyIds.length; i++) {

if (this.keyIds[i] === keyId) {

// const UNDEFINED = new Object();

if (this.objs[i] === UNDEFINED) {

this.objs[i] = this._new(this._providers[i]);

}

return this.objs[i];

}

}

return UNDEFINED;

}

用于创建对象

// 创建依赖对象

_new(provider: ResolvedReflectiveProvider): any {

// 判断是否存在循环依赖

if (this._constructionCounter++ > this._getMaxNumberOfObjects()) {

throw cyclicDependencyError(this, provider.key);

}

return this._instantiateProvider(provider);

}

// 获取最大的对象个数

private _getMaxNumberOfObjects(): number { return this.objs.length; }

// 根据已解析的provider创建依赖对象。若是multi provider则,循环创建multi provider对象。

private _instantiateProvider(provider: ResolvedReflectiveProvider): any {

if (provider.multiProvider) {

const res = new Array(provider.resolvedFactories.length);

for (let i = 0; i < provider.resolvedFactories.length; ++i) {

res[i] = this._instantiate(provider, provider.resolvedFactories[i]);

}

return res;

} else {

return this._instantiate(provider, provider.resolvedFactories[0]);

}

}

// 根据已解析的provider和已解析的工厂创建依赖对象

private _instantiate(

provider: ResolvedReflectiveProvider,

ResolvedReflectiveFactory: ResolvedReflectiveFactory): any {

// 获取对象工厂函数

const factory = ResolvedReflectiveFactory.factory;

// 获取工厂函数所依赖的对象列表

let deps: any[];

try {

deps = ResolvedReflectiveFactory.dependencies

.map(dep => this._getByReflectiveDependency(dep));

} catch (e) {

if (e.addKey) {

e.addKey(this, provider.key);

}

throw e;

}

// 调用对象工厂函数创建依赖对象

let obj: any;

try {

obj = factory(...deps);

} catch (e) {

throw instantiationError(this, e, e.stack, provider.key);

}

return obj;

}

用于获取工厂函数依赖对象

// 若通过@Optional装饰器定义该依赖对象,表示该依赖对象是可选的,当获取不到时返回null。

private _getByReflectiveDependency(dep: ReflectiveDependency): any {

return this._getByKey(dep.key, dep.visibility, dep.optional ? null : THROW_IF_NOT_FOUND);

}


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:java数据结构与算法之简单选择排序详解
下一篇:详解Vue中使用v
相关文章

 发表评论

暂时没有评论,来抢沙发吧~