现在的位置: 首页 > 综合 > 正文

SwiftSuspenders 1.6-深入浅出1

2011年12月24日 ⁄ 综合 ⁄ 共 2408字 ⁄ 字号 评论关闭

深入

         这篇SwiftSuspenders 浅出深入的 深入部分主要是对SwiftSuspenders进行深度剖析,包括对SwiftSuspenders的体系结构的分析,一个对象在整个注入过程中会经历怎样的生命周期,以及对SwiftSuspenders每个类的详细解读。

术语表

首先为了表达的明确性,先列下了一些可能在文章中用到的术语。这样便于减少理解上的歧义:

为了解释清楚术语之间的关系,我们设计以下场景以进行类比:闪闪同学生病了,需要进行打针治疗。

术语名

英文

解释

依赖

Dependency

面向对象中类之间的关系,简单来说,当A类的某些功能需要B类进行辅助时,就说A类对B类有依赖。如闪闪同学需要药来治病,那么就说闪闪对药有依赖

注入

Injection

一种建立依赖关系的行为。如闪闪同学要使用药,就必须让药进入体内(引用关系)。如何让药进入体内呢?需要一个针筒,通过注射来获得药物。这就是注入。当AB的依赖关系由C来建立。BC注入进了A

注入器

Injector

就是SwiftSuspenders里面的Injector类的一个实例,相当于扮演针筒的角色。

注入配置

InjectionConfig

是针对一个注入行为的配置对象。包含注入请求的类和注入名。所使用的注入器和返回结果的策略等信息。如闪闪得的是感冒,需要注射感冒药,还需要注射消炎药,这时候闪闪就要请求两种类型的药。同一种类型的药,可能还有不同的品牌,所以有的时候还需要加上请求的药的名字,就相当于注入名。注入配置就相当于一张处方单。

注入点

InjectionPoint

依赖注入分几种形式,如,构造函数注入,属性注入和方法注入。这些都称做注入点。比如打针,可以打PP,也可以打胳膊。属性注入就是对public的属性或者有setter方法进行复制,方法注入就是像某个函数传参。

注入描述

InjecteeDescription

包含了一个被注入对象的所有的注入点。比如闪闪打针,需要在胳膊打一针,需要在屁股打两针。就会描述在注入描述里面。InjecteeDescriptionInjector的一个包外类。

返回策略

InjectionResult

反应了注入器以何种方式对请求进行注入,如直接新建一个B对象,然后注入A,或者以单例模式新建一个B对象,然后所有使用B的注入都会共享同一个对象等等。

 

体系结构

SwiftSuspenders 1.6 浅出深入 深入 (1) - sswilliam - 闪闪小巴依

 

SwiftSuspenders的类图如上图所示。整个框架以Injector为核心。InjectionPoint包中包含了所有与注入点相关的类,InjectionResult包中包含了返回策略相关的类。其他的类都是配合Injector类进行工作。具体的类的解读会在下一章进行深入介绍。

其中用到的设计模式主要有策略模式,模板方法。

InjectionResult包中主要使用了通过策略模式,作者针对不同的需求创造了不同的映射策略,如单例模式,类模式,对象模式。同时还允许开发者开发其他所需的策略。

InjectionPoint包中主要使用了模板方法,通过让不同的子类实现initializeInjection这个钩子(hook)方法从而实现不同的注入点

对象生命周期

         这一章主要从内部分析SwiftSuspender的两个主要活动:映射和注入的流程

映射顺序图

 

 SwiftSuspenders 1.6 浅出深入 深入 (1) - sswilliam - 闪闪小巴依

mapClass为例,首先主程序调用InjectormapClass方法,传入所需的参数;

然后Injector调用自身的getMapping方法,获得一个相应的注入配置对象,如果再此之前已经建立过相应的注入配置,则直接返回,如果没有,就会新建一个注入配置对象

获得注入配置对象后,就会调用得到的InjectionConfigsetResult方法设置该配置的返回策略。如为类映射是,就设置为InjectClassResult。如果是单例,则设置为InjectSingletonResult。以此类推。

最后返回设置好各项参数的InjectionConfig。同时该InjectionConfig对象就会存在Injectorm_mappingsDictionary中。整个映射的过程就完成了。

注入顺序图

SwiftSuspenders 1.6 浅出深入 深入 (1) - sswilliam - 闪闪小巴依

通过InjectorgetInstance()方法可以获得注入后的对象。主程序通过向Injector发送类+注入名的请求以获得对象。

Injector得到请求后,调用自身的getConfigurationForRequest()方法获得相应的InjectionConfig注入配置.

获得注入配置后,调用InjectionConfiggetResponse()方法获得结果。

InjectionConfiggetResponse()方法会调用相应的InjectionResult返回策略的getResponse()方法获得结果。如果traverseAncestors设为true,那么当在当前的注入器中没有找到相应的注入配置时,还会从下至上依次遍历其祖先注入器,直到找到位置。

InjectionResult会调用Injectorinstantiate()方法获得对象。

Injectorinstantiate方法会调用InjectorgetInjectionPoints方法获得需要注入的类的所有的注入点。然后调用构造函数注入点先获得所请求类的实例。

在得到请求类的实例后,Injector会调用自身的InjectInto方法像这个对象的其他注入点进行依赖注入。

最后将注入完成的结果返回给程序。在注入的过程中,如果遇到被注入的对象仍然需要依赖注入,就会和上面的流程一样,对被注入的对象同样执行依赖注入,然后再将注入完的对象注入进目标对象。

转http://sswilliam.blog.163.com/blog/static/189696383201176114713922/

抱歉!评论已关闭.