zoukankan      html  css  js  c++  java
  • 认识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

  • 相关阅读:
    RabbitMq安装笔记
    SpringBoot笔记--Jackson
    SpringBoot笔记--FastJson
    由一个“两次请求”引出的Web服务器跨域请求访问问题的解决方案
    转:SpringMVC之类型转换Converter(GenericConverter)
    npm 命令
    数据分页技巧
    Mongo 开发笔记
    Android 开发
    Bash 笔记
  • 原文地址:https://www.cnblogs.com/kevinchu/p/3782571.html
Copyright © 2011-2022 走看看