认识Robotlegs(一)注入过程的分析

提到Robotlegs,很多人都读过一篇叫做《Robotlegs最佳实践》的教程,都知道Robotlegs是一个基于IOC的MVC微框架,其内部的注入机制有三种绑定规则(值绑定、类绑定、
单例绑定),现在我以SwiftSuspenders的视角再来分析一下注入的实现过程。

SwiftSuspenders实现注入的过程大致是下面的步骤:

1)创建注入器

2)添加注入规则

3)初始化注入宿主(InjecteeClass)

4)对注入宿主进行注入 (把注入对象注入到宿主内部)


 1 /**注入对象*/
2 package
3 {
4 public class InjectObject
5 {
6 public function InjectObject()
7 {
8 trace("InjectObject Created");
9 }
10 public function call():void
11 {
12 trace("InjectObject Called");
13 }
14 }
15 }
16
17
18 /**注入宿主*/
19 package
20 {
21 public class InjecteeClass
22 {
23 [Inject]
24 public var injectPoint:InjectObject;
25 public function InjecteeClass()
26 {
27 trace("InjecteeClass Created");
28 //injectPoint.call();
29 }
30 [PostConstruct(order=1)]
31 public function order1():void
32 {
33 trace("InjecteeClass PostConstruct");
34 injectPoint.call();
35 }
36 }
37 }
38
39
40 /**程序*/
41 package
42 {
43 import flash.display.Sprite;
44 import org.swiftsuspenders.Injector;
45 public class InjectorTest extends Sprite
46 {
47 public function InjectorTest()
48 {
49 var injector:Injector = new Injector();
50 injector.mapClass(InjectObject, InjectObject);
51
52 /**方式1*/
53 var instance:InjecteeClass = new InjecteeClass();
54 injector.injectInto(instance);
55
56 /**方式2*/
57 injector.mapClass(InjecteeClass, InjecteeClass);
58 var instance:InjecteeClass = injector.getInstance(InjecteeClass);
59

60 /**方式3*/
61 var instance:InjecteeClass = injector.instantiate(InjecteeClass);
62 }
63 }
64 }

输出
--------------------------------------------
InjecteeClass
Created
InjectObject Created
InjecteeClass PostConstruct
InjectObject
Called

代码分析 var injector:Injector = new Injector(); 创建注入器 (过程1)

injector.mapClass(InjectObject, InjectObject); 为注入器增加注入规则(过程2)
此处增加的注入规则是:在需要InjectObject的地方创建一个新的InjectObject实例并注入。

[Inject]  public var injectPoint:InjectObject;
此处需要注入InjectObject,根据注入器的注入规则会创建一个新的InjectObject实例并注入到injectPoint类变量。(过程4)
实际上实现过程4需要调用注入器的injectInto方法,只有在调用了注入器的injectInto方法时才会真正进行注入。

在完成过程4之前还需要初始化注入宿主类(过程3) 注入宿主类是指内部有注入需求的类。注入分为类属性注入和类构造注入,这里只讨论类属性注入的情况。
类属性即类变量,需要public访问控制符,因为注入是从类外部进行的,所以只有那些public属性才能接收注入。 SwiftSuspenders
提供的初始化宿主类并实现注入的写法有三种,对应有如下代码(任用一种即可):


/**方式1*/
var instance:InjecteeClass = new InjecteeClass();
injector.injectInto(instance);

/**方式2*/
injector.mapClass(InjecteeClass, InjecteeClass);
var instance:InjecteeClass = injector.getInstance(InjecteeClass);

/**方式3*/
var instance:InjecteeClass = injector.instantiate(InjecteeClass);

方式1最清晰,先实例化宿主类InjecteeClass,然后用注入器的injectInto方法按规则将对象注入到InjecteeClass内部。
没有injectInto将不会有注入的行为,也就是说示例中InjecteeClass的injectPoint属性为null。

方式2实现注入和方式1有所不同,但是结果是一样的。 首先要做的是实例化InjecteeClass,这里没有直接实例化,而是通过注入规则实现实例化。

injector.mapClass(InjecteeClass,
InjecteeClass)设定了注入规则,当需要InjecteeClass的时候创建一个新的InjecteeClass对象。
injector.getInstance(InjecteeClass)这句实现按注入规则获得一个InjecteeClass对象实例,并对该实例进行injectInto操作。
所以方式2和方式1是一样的流程,不同的是方式2为InjecteeClass也创建了注入规则。

方式3可以看作方式2的简化写法,
injector.instantiate()会自动创建注入规则(mapClass)并完成注入(injectInto)。

上面提到完成注入需要的过程有4步:创建注入器、添加注入规则、初始化注入宿主、对宿主进行注入。

如果在宿主类InjecteeClass的构造方法中访问injectPoint只会得到一个空值,因为真正的注入尚未完成。

那么怎样才能在宿主类InjecteeClass构造完成后马上访问injectPoint呢?答案是可以的,SwiftSuspenders
会在注入完成后立即调用带有[PostConstruct(order=1)]标签的方法(如果有多个,按order序号顺序调用),在这个方法中就可以访问injectPoint。

最后总结一下,整个注入的详细流程是这样的:

1)创建一个注入器Injector对象。

2)为Injector添加注入规则

3)初始化宿主类InjecteeClass

4)对InjecteeClass进行injectInto

5)遍历InjecteeClass内部带有[Inject]标签的类属性,查找注入规则获取注入对象实例并赋值给该属性。

6)调用带有[PostConstruct]的类方法

其中5和6是injectInto之后SwiftSuspenders自动完成的。

KevinChu

2014/6/6

认识Robotlegs(一)注入过程的分析,布布扣,bubuko.com

时间: 2024-11-12 14:32:32

认识Robotlegs(一)注入过程的分析的相关文章

struts2请求过程源代码分析

struts2请求过程源代码分析 Struts2是Struts社区和WebWork社区的共同成果.我们甚至能够说,Struts2是WebWork的升级版.他採用的正是WebWork的核心,所以.Struts2并非一个不成熟的产品,相反.构建在WebWork基础之上的Struts2是一个执行稳定.性能优异.设计成熟的WEB框架. 我这里的struts2源代码是从官网下载的一个最新的struts-2.3.15.1-src.zip.将其解压就可以. 里面的文件夹页文件很的多,我们仅仅须要定位到stru

网络中数据传输过程的分析

网络中数据传输过程的分析 我们每天都在使用互联网,我们电脑上的数据是怎么样通过互联网传输到到另外的一台电脑上的呢?把自己的理解写一下,可能有很多细节还没有能的很清楚!希望在以后可以使之更加的完善!有不对的地方还请指正.     我们知道现在的互联网中使用的TCP/IP协议是基于,OSI(开放系统互联)的七层参考模型的,(虽然不是完全符合)从上到下分别为 应用层 表示层 会话层 传输层 网络层 数据链路层和物理层.其中数据链路层又可是分为两个子层分别为逻辑链路控制层(Logic Link Cont

Android Content Provider的启动过程源代码分析

本文参考Android应用程序组件Content Provider的启动过程源代码分析http://blog.csdn.net/luoshengyang/article/details/6963418和<Android系统源代码情景分析>,作者罗升阳. 0.总图流程图如下: 1.MainActivity进程向ActivityServiceManager主线程发送GET_CONTENT_PORVIDER_TRANSACTION 如下图: 如图:第一步 ~/Android/frameworks/b

Android --- Zygote和System进程启动过程简要分析

Android --- Zygote和System进程启动过程简要分析 在看过<Android情景源代码>的Zygote启动章节后,作如下简要总结.Zygote进程在init进程启动过程中被以service服务的形式启动: service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server class main socket zygote stream 660 root syste

Android系统进程间通信(IPC)机制Binder中的Client获得Server远程接口过程源代码分析

文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6633311 在上一篇文章中,我 们分析了Android系统进程间通信机制Binder中的Server在启动过程使用Service Manager的addService接口把自己添加到Service Manager守护过程中接受管理.在这一篇文章中,我们将深入到Binder驱动程序源代码去分析Client是如何通过Service Manager的

反编译C程序为汇编代码,汇编代码执行过程的分析与思考

张韩+ 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 系统:32位Ubuntu14.04 编写C程序:(保存至main.c) int g(int x) {   return x + 3; } int f(int x) {   return g(x); } int main(void) {   return f(8) + 1; } 控制台反编译命令: 得到main.s,其内容如下:

Android应用程序绑定服务(bindService)的过程源代码分析

文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6745181 Android应用程序组件Service与Activity一样,既可以在新的进程中启动,也可以在应用程序进程内部 启动:前面我们已经分析了在新的进程中启动Service的过程,本文将要介绍在应用程序内部绑定Service的过程,这是一种在应用程序进程内部启动 Service的方法. 在前面一篇文章Android进程间通信(IPC)机

Android系统默认Home应用程序(Launcher)的启动过程源代码分析

在前面一篇文章中,我们分析了Android系统在启动时安装应用程序的过程,这些应用程序安装好之后,还需要有一个 Home应用程序来负责把它们在桌面上展示出来,在Android系统中,这个默认的Home应用程序就是Launcher了,本文将详细分析 Launcher应用程序的启动过程. Android系统的Home应用程序Launcher是由ActivityManagerService启动的,而 ActivityManagerService和PackageManagerService一样,都是在开

Android应用程序安装过程源代码分析

文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6766010 Android系统在启动的过程中,会启动一个应用程序管理服务PackageManagerService,这个服务 负责扫描系统中特定的目录,找到里面的应用程序文件,即以Apk为后缀的文件,然后对这些文件进解析,得到应用程序的相关信息,完成应用程序的安装过程, 本文将详细分析这个过程. 应用程序管理服务PackageManagerSe