Spring Actionscript IOC 框架与 Flex Cairngorm MVC 应用开发的整合

在之前的文章中,分别介绍过如何使用 Spring Actionscript IOC 框架和基于 Cairngorm MVC 框架的应用开发,那么如何将二者有效地结合起来,将 IOC 和 MVC 的优势一起结合到我们的 Flex 应用开发中是这篇文章的主要内容。

翟 峰, 开发工程师, IBM

翟峰在 J2EE 和 Web 开发领域有着多年开发经验,喜欢关注新技术。毕业于西北大学,拥有计算机硕士学位。



2011 年 6 月 16 日

要学习本教程,您需要有一定的 Flex 编程经验,以及对 Cairngorm MVC 和 Spring Actionscript IOC 框架有所了解。

Spring Actionscript 框架简介

Spring Actionscript 是一种类似于基于 Java 的 Spring IOC 框架的 Actionscript3 语言的实现,它可以应用于 Flash、Flex 和 AIR 的开发。这个框架不仅仅是一个能够支持控制反转的容器,它也提供了和现有的 Flex MVC 框架的集成方案,比如和 Cairngorm 的集成。本文就会着重介绍它如何与 Cairngorm MVC 集成在一起,发挥 IOC 与 MVC 的优势,使得 Flex 应用程序能够更大程度地实现灵活和健壮。在阅读本文之前,需要对 Spring Actionscript 和 Cairngorm 框架有所了解。


Spring Actionscript 与 Cairngorm 集成的扩展点介绍

Spring Actionscript 框架提供了多个扩展点用于和 Cairngorm 框架集成,它会将 Cairngorm 的一些核心对象配置到 Spring Actionscript 的 IOC 容器内,其中的一些特性会使我们在使用这个 MVC 框架的时候更加容易,使得我们的代码更加灵活。这篇文章会从各个扩展点进行详细介绍,如何配置以及将二者结合起来使用。首先我们先了解一下有哪些扩展点需要集成:

  • ModelLocator 用于管理 Model 对象。
  • FrontController 用于管理事件和 Command 之间的绑定关系。
  • ServiceLocator 用于配置所有与后台通信的服务。
  • Command 工厂 用于创建 Command 对象
  • Delegate 工厂 用于创建 Delegate 对象

通过这些扩展点的集成,才会将 Sprint Actionscript 与 Cairngorm MVC 框架紧密的结合起来,才能更好的发挥二者的优势。下面我们分别仔细介绍一下各个扩展点是如何使用的:

ModelLocator

这是在 Cairngorm 框架中很重要的一个类,用于获取应用中的各个 Model 对象,例如想要获得一个 Model 的实例,你需要通过它的一个静态方法 ApplicationModel.getInstance() 方法。它大量的依赖于单例模式,在方便使用的同时,也使得你的代码和具体的 Model 实现类紧紧地绑定起来。而这正和“低耦合”的思想恰恰相反,想要解决这个问题,最好的解决办法是提供 Model 接口,用你的具体 Model 类去实现这个接口,通过面向接口的方式将 Model 注入到 Flex 应用中,首先我们创建一个简单的 Model 接口:

清单 1.
 public interface IApplicationModel extends IEventDispatcher { 
     
    function get productItems():ArrayCollection; 

    [Bindable(event="productItemsChanged")] 
    function set productItems(value:ArrayCollection):void; 

 }

然后让你的具体的 ModelLocator 类现这个接口,就像下面的代码:

清单 2.
public class ApplicationModel extends EventDispatcher implements IModelLocator,
             IApplicationModel{        
    private static var _modelInstance : IApplicationModel; 

  // 单例, 用以返回 model 实例 
  public static function getInstance():IApplicationModel { 
        if (!_modelInstance) { 
          _modelInstance = new ApplicationModel(); 
        } 

        return _modelInstance; 
    } 

    public function ApplicationModel():void { 
        super(); 
        if (_modelInstance) { 
            throw new Error('Only one ApplicationModel instance should be instantiated'); 
        } 
    } 

    private var _productItems:ArrayCollection; 
    
    public function get productItems():ArrayCollection{ 
        return _productItems; 
    } 

    [Bindable(event="productItemsChanged")] 
    public function set productItems(value:ArrayCollection):void{ 
        if (value !== _productItems) { 
            _productItems = value; 
            dispatchEvent(new Event("productItemsChanged")); 
        } 
    } 
 }

现在我们将它配置到我们的 Spring ActionScript IOC 容器中,

 <object id="appModelInstance" class="com.myclasses.cairngorm.ApplicationModel" 
    factory-method="getInstance" scope="singleton"/>

现在我们用 IoC 容器来管理我们的 Model 类的创建,我们的代码里不需要 getInstance() 工厂方法了,当你使用了 scope="singleton" 属性,IoC 容器内会确保只有一个 Model 实例被创建。所有我们的 Model 类可以被重构为:

清单 3.
 public class ApplicationModel extends EventDispatcher implements IModelLocator, 
        IApplicationModel { 

    public function ApplicationModel():void { 
        super(); 
    } 

   private var _productItems:ArrayCollection; 
    
    public function get productItems():ArrayCollection { 
      return _productItems; 
    } 
    
    [Bindable(event="productItemsChanged")] 
    public function set productItems(value:ArrayCollection):void { 
        if (value !== _productItems) { 
            _productItems = value; 
            dispatchEvent(new Event("productItemsChanged")); 
        } 
    } 
 }

然后修改我们的配置文件,去掉工厂方法的配置:

 <object id="applicationModel" class="com.myclasses.cairngorm.ApplicationModel" 
    scope="singleton"/>

就是这么简单,利用 Spring Ioc 容器使得我们的 Model 层的代码更加简洁。

FrontController

用过 Cairngorm 都知道 FrontController 类的重要,它是 MVC 框架中重要的中央控制器,它负责将我们的事件和我们的 Command 执行层绑定起来。在使用 Cairngorm 框架的时候,如果没有 IoC 容器管理,我们需要将 FrontController 类和 ServiceLocator 类(稍后会提到)添加到你的主应用程序的 MXML 类中,从而编译到最终的 Swf 文件里。就像下面的代码:

清单 4.
 <mx:Application 
    xmlns:control="com.cairngormclasses.control.*"
    xmlns:business="com.cairngormclasses.business.*"
   xmlns:mx="http://www.adobe.com/2006/mxml" 
    layout="absolute"> 
    <control:Controller id="frontController"/> 
    <business:Services id="serviceLocator"/> 
 </mx:Application>

在你的 FrontController 类中绑定事件和 commands 之后,FrontController 类会变得像下面一样:

清单 5.
				 public class Controller extends FrontController { 
        
    public static const SOME_ACTION:String = "SomeActionEventID"; 
    
    public function Controller() { 
        super(); 
        initializeCommands(); 
    } 
   // 将事件和 command 绑定起来 
   public function initializeCommands():void { 
     addCommand( Controller.SOME_ACTION, SomeActionCommand ); 
    } 
 }

这样的代码是可以运行的,但是将事件和 command 类的绑定关系写到 controller 类里面带来的问题是,如果需要改变这种绑定关系,就需要改写这个 Controller 类然后重新编译应用。于是 Spring Actionscript 框架提供了 CairngormFrontController,这个类允许将事件的 ID 和 Command 在 IoC 容器的配置文件中绑定起来。比如下面的配置:

清单 6.
 <object id="frontController" class="
 org.springextensions.actionscript.cairngorm.control.CairngormFrontController" 
 scope="singleton"> 
 <constructor-arg> 
  <object> 
 <!-- Add a new property for each event/command mapping: --> 
 // 绑定事件和 command 
          <property name="SomeActionEventID" value="SomeActionCommand"/> 
  </object> 
 </constructor-arg> 
 <!-- The following argument is optional --> 
 // 指明 commad 类所在的包路径 
 <constructor-arg value="com.mycommands.command"/> 
 </object>

第一个参数是个对象,它包含事件 ID 和 Command 类的关联,第二个参数是指明 Command 类的包名。通过这样配置之后,我们就不再需要 FrontController 类了,但是我们还是必须将 Command 类编译到应用程序的 Swf 文件内用于运行期的动态反射

这样之后,我们之前的 FrontController 和 ServiceLocator 类就不需要在应用中声明了:

清单 7.
 <mx:Application 
 xmlns:control="com.cairngormclasses.control.*"
 xmlns:business="com.cairngormclasses.business.*" 
 xmlns:mx="http://www.adobe.com/2006/mxml"
 layout="absolute"> 
 // 删除 FrontController 和 serviceLocator 的声明 
  <!-- control:Controller id="frontController"/ --> 
  <!-- business:Services id="serviceLocator"/ --> 
 </mx:Application>

ServiceLocator

现在我们来看看 ServiceLocator 类,在源代码里配置远程服务不是很方便,而且当在开发时期和运行时期的远程服务路径不一致的时候就会带来一些麻烦,任何改变都需要重新编译应用程序。所以当引入 Spring Actionscript 之后,这些配置的改变就可以抽到 xml 配置文件里,任何改动都不要重新编译了。Spring Actionscript 提供的 CairngormServiceLocator 能够支持在 IoC 容器中配置服务,例如:

清单 8.
<object id="serviceLocator" 
   class="org.springextensions.actionscript.cairngorm.business.CairngormServiceLocator" 
       factory-method="getInstance"> 
<!-- The CairngormServiceLocator is marked with the dynamic keyword, 
    //so new properties can be added at runtime: --> 
      // 用于指定需要用的 service 
     <property name="testService"> 
      <ref> testService</ref> 
  </property> 
 </object>

元素 <ref/> 用于指定配置的 testService,它的配置定义如下:

清单 9.
 <object id="testService" class="mx.rpc.remoting.mxml.RemoteObject" scope="singleton"> 
  <property name="id" value="testService"/> 
 <property name="endpoint" value="/flex2gateway/"/> 
  <property name="destination="ColdFusion"/> 
  <property name="source" value="com.myremoteobjects.someservice"/> 
  <property name="showBusyCursor" value="true"/> 
  <property name="makeObjectsBindable" value="true"/> 
 </object>

Command 工厂

FrontController 通常用来实例化 Command 类,并将它绑定到事件上,在 Command 中,如果需要访问 Model 实例,通常的做法是直接调用 applicationModel.getInstance() 方法。这就是一种紧耦合的实现方式,而且这也会使得单元测试更加困难,所以如何在 Command 中注入别的实例,例如 Model,Spring Actionscript 提供了 IcommandFactory 接口去解决这个问题,这个接口非常简单,只需要实现以下两个方法:

 public function canCreate(clazz:Class):Boolean; 
 public function createCommand(clazz:Class):ICommand

方法 canCreate 用于决定请求的 CommandClass 是否可以被具体的 Command 工厂创建,在这个方法里,你需要检查是否这个 Command 类实现了具体的接口,或者在运行期需找注入的 Command 类。CairngormFrontcontroller 实际上在内部实现了这个接口,ICommandFactory 实现了去检查是否某一个具体的类实现了了 ICommand 接口。

现在我们看看如何解决这个 model 注入的问题,我们先定义一个接口 IApplicationModelAware.

 public interface IApplicationModelAware { 
    function set applicationModel(value:IApplicationModel):void; 
 }

然后可以去创建一个 Command 基类,它负责获取 model 的引用:

清单 10.
public class CommandBase extends AbstractResponderCommand 
           implements IApplicationModelAware { 
            
    public function CommandBase() { 
        super(); 
    } 

    private var _applicationModel:IApplicationModel; 
    
    function get applicationModel():IApplicationModel { 
        return _applicationModel; 
    } 
   // 用于注入 model 
    function set applicationModel(value:IApplicationModel):void { 
        _applicationModel = value; 
    } 
   // 执行方法 
    override public function execute(event:CairngormEvent):void { 
        super.execute(event); 
    } 
    // 成功回调函数,需要被子类覆盖
    override public function result(data:Object):void { 
        throw new Error("Not implemented in base class"); 
    } 
 // 失败回调函数,需要被子类覆盖
    override public function fault(info:Object):void { 
        throw new Error("Not implemented in base class"); 
    } 
    
 }

下面我们去创建 Command 工厂类,它负责创建 Command 的子类,以及注入 model 的引用。

清单 11.
 public class ApplicationModelAwareCommandFactory implements ICommandFactory, 
            IApplicationModelAware { 
   // 用于注入 model 
    private var _applicationModel:IApplicationModel; 
    function set applicationModel(value:IApplicationModel):void { 
        _applicationModel = value; 
    } 

    public function canCreate(clazz:Class):Boolean { 
        return (ClassUtils.isSubclassOf(clazz, CommandBase)); 
    } 
    public function createCommand(clazz:Class):ICommand { 
        var result:CommandBase = new clazz(); 
        result.applicationModel = _applicationModel; 
        return result; 
    } 
 }

我们看到 ApplicationModelAwareCommandFactory 实现了 IApplicationModelAware 接口,现在为了能够将 model 注入到我们的工厂类中,我们需要在 Spring Actionscript 容器中进行配置,首先配置 command 工厂:

清单 12.
<obj ect id="appAwareCmdFactory" 
  class="com.myclasses.cairngorm.factories.ApplicationModelAwareCommandFactory" 
     scope="singleton"> 
 <property name="applicationModel" ref="appModelInstance"/> 
 </object>

接下来,我们需要将这个 command 工厂类也注入到我们的 controller 中:

 <object id="frontController" 
 class="org.springextensions.actionscript.cairngorm.control.CairngormFrontController" 
    scope="singleton"> 
 <constructor-arg> 
  <object> 
   <property name="SomeActionEventID" value="SomeActionCommand"/> 
  </object> 
 </constructor-arg> 
 <!-- The followoing argument is optional --> 
 <constructor-arg value="com.mycommands.command"/> 
 <!-- Add a custom command factory instance --> 
 // 配置 command 工厂
 <method-invocation name="addCommandFactory"> 
  <arg><ref>appAwareCmdFactory</ref></arg> 
 </method-invocation> 
 </object>

现在,每一个添加到 FrontController 中的 command, 都会自动注入了 ApplicationModel 的引用,其他的注入类似。

Delegate 工厂

熟悉 Cairngorm 就会知道,delegate 类是用来和后台应用交互,发送以及接受数据用的,往往在 command 中需要引用 delegate 来完成完整的业务逻辑。我们在 command 类中创建具体需要的 delegate 类的实例,就像下面的例子,直接创造具体的 delegate:

清单 13.
 public class GetProductItemsCommand extends CommandBase { 
    private var _delegate:GetProductItemsDelegate; 
    
    public function GetProductItemsCommand() { 
        super(); 
        //create the specific delegate class and pass ourselves as its responder 
        // 创建具体的 delegate 对象
        _delegate = new GetProductItemsDelegate(this as IResponder); 
    } 

    override public function execute(event:CairngormEvent):void { 
       super.execute(event); 
       //execute the delegate logic 
       _delegate.getProductItems(); 
    } 

    override public function result(data:Object):void { 
        // Business logic to handle the data retrieval 
    } 

    override public function fault(info:Object):void { 
        // Logic to handle errors 
    } 
    
 }

这样带来的问题就是我们将 command 和 delegate 又牢牢地绑定在了一起。如果需要改变使用的 delegate,就会带来一些不方便,而且需要重新编译。 基于这种问题,Spring Actionscript 提供了一个接口叫 IBusinessDelegate,我们的 delegate 例子继承这个接口:

 public interface IGetProductItemsDelegate extends IBusinessDelegate { 
 
    function getProductItems():void; 
 }

这个接口的实现可以继承 Spring Actionscript 提供的 AbstractBusiesssDelegate 类

清单 14.
 public class GetProductItemsDelegate extends AbstractBusinessDelegate 
         implements IGetProductItemsDelegate { 
    
    public function GetProductItemsDelegate(service:* = null, 
                 responder:IResponder = null) { 
        super(service, responder); 
    } 
 
    public function getProductItems():void { 
        var token:AsyncToken = service.getProductItems(); 
        token.addResponder(this.responder); 
    } 
 }

现在是时候去重构我们的 command 类了,我们的 command 类已经继承了 AbstractResponderCommand 类,这个基类已经包含了一个叫做 businessDelegate 的属性,我们不再需要手工去创建 delegate 的实例,我们只需要将需要的 delegate 注入进来,然后将 businessDelegate 属性转化成我们需要的 delegate 接口。

清单 15.
 public class GetProductItemsCommand extends CommandBase { 
    public function GetProductItemsCommand() { 
        super(); 
    } 

    override public function execute(event:CairngormEvent):void { 
        super.execute(event); 
        // 通过 businessDelegate 属性获得注入的 delegate 对象 
      IGetProductItemsDelegate(this.businessDelegate).getProductItems();
      } 

    override public function result(data:Object):void { 
        // Business logic to handle the data retrieval 
    } 

    override public function fault(info:Object):void { 
        // Logic to handle errors 
    } 
 }

接下里我们看如何将这个 delegate 注入到被 command 工厂创建出来的 command 中,Spring actionscript 提供了一个叫做 RespondCommandFactory 的类去完成这个工作,它提供了一个叫做 addBusinessDelegateFactory 的方法:需要将我们的 command 工厂继承它:

清单 16.
 public class ApplicationModelAwareCommandFactory extends ResponderCommandFactory 
           implements IApplicationModelAware { 

 }

最后,我们需要配置到 IOC 配置文件中,我们首先来配置 BusinessDelegate 工厂:

清单 17.
 <object id="businessDelegateFactory"
   class="org.springextensions.actionscript.cairngorm.business.BusinessDelegateFactory" 
       scope="singleton"> 
  <property name="service" ref="testService"/> 
  <property name="delegateClass" type="class" 
     value="com.myclasses.delegates.GetProductItemsDelegate"></property> 
 </object>

然后我们需要将这个 delegate 工厂和我们的 command 工厂联系起来:

清单 18.
 <object id="appAwareCmdFactory" 
     class="com.myclasses.cairngorm.factories.ApplicationModelAwareCommandFactory" 
        scope="singleton"> 
  <property name="applicationModel" ref="appModelInstance"/> 
  <method-invocation name="addBusinessDelegateFactory"> 
    <arg> 
      <ref>businessDelegateFactory</ref> 
    </arg> 
    <arg> 
      <array> 
        <value type="Class">com.myclasses.commands.GetProductItemsCommand</value> 
      </array> 
    </arg> 
  </method-invocation> 
 </object>

现在,我们基于 Cairngorm MVC 的应用都通过 Spring Actionscript 容器变得松散耦合起来了,今后很多的重构都只需要改改配置文件,Flex 应用的可维护性和可扩展性都得到了大大的提高。


安装配置开发环境

开始前先让我们来搭建我们的开发环境:

下载并安装JDK( 本文使用版本为 Sun JDK 6)

下载并解压Eclipse( 本文使用版本为 Eclipse Ganymede J2EE SR2 版本 )

下载并安装FB3_WWEJ_Plugin.exe(Flex Builder plug-in for eclipse)

安装 FB3_WWEJ_Plugin.exe 过程中选中 eclipse 安装目录。


一个入门的小例子

前面我们讲解了 Spring Actionscript 如何与 Cairngorm MVC 框架一起使用,下面我用一个简单的小例子来进一步的理解开发过程,通过以下代码示例,就会理解如何配置以及使用 Spring Actionscript IOC 容器。

  • 下载并解压 Spring Actionscript

    解压出来主要包括以下文件:

    spring-Actionscript-core-1.0RC1.swc (核心类)

    spring-Actionscript-cairngorm-1.0RC1.swc (与 cairngorm mvc 框架集成)

    依赖库:

    as3commons-lang.swc

    as3commons-logging.swc

    as3commons-reflect.swc

  • 下载并解压 Cairngorm 2.2

    解压出来就是一个 Cairngorm.swc 文件

  • 新建 Flex Project
    图 1. 新建项目
    图 1. 新建项目

    点击 Finish,将以下 swc 拷贝到项目的 flex_libs 目录下

    图 2. 目录结构
    图 2. 目录结构

在 flex_src 目录下建好包结构,创建 application-context.xml 用于配置对象以及之间的依赖关系。

这个配置文件用于配置以上介绍的扩展点,比如 ModelLocator,FrontController,Command 工厂等。

清单 19. 配置文件
 <?xml version="1.0" encoding="utf-8"?> 
 <objects 
  xmlns="http://www.springactionscript.org/schema/objects"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:si="http://www.springactionscript.org/schema/stageinterception"
  xsi:schemaLocation="http://www.springactionscript.org/schema/objects 
  http://www.springactionscript.org/schema/objects/spring-actionscript-objects-1.0.xsd"> 
 <! — modelLocator 的配置 --> 
 <object id="appModelLocator" class="model.MyModelLocator" scope="singleton"/> 
 <!-- front controller 的配置 --> 
 <object id="frontController" 
   class="org.springextensions.actionscript.cairngorm.control.CairngormFrontController"
 scope="singleton"> 	
 <constructor-arg> 
 <object> 
 <! — event 和 command 的绑定 --> 
	 <property name="AddPerson" value="commands.AddPersonCommand" /> 
	 <property name="LoadPersons" value="commands.LoadPersonCommand" /> 
	 </object> 
 </constructor-arg> 
 <! —配置创建上述 command 的工厂 --> 
 <method-invocation name="addCommandFactory"> 
  <arg><ref>appAwareCmdFactory</ref></arg> 
 	 </method-invocation> 		
 </object> 	
 <! — service locator 的配置 --> 
	 <object id="serviceLocator" 
 class="org.springextensions.actionscript.cairngorm.business.CairngormServiceLocator"
      factory-method="getInstance"> 
  <! —配置需要注入的 service--> 
	  <property name="personInfosService"> 
	    <ref>personInfosService</ref> 
	  </property> 
	 </object> 

 <! — HTTP service 的配置 --> 
 <object id="personInfosService" class="mx.rpc.http.mxml.HTTPService" scope="singleton"> 
 <property name="url" value="xml/peopleinfo.xml"/> 
 </object> 	

 <!--Delegate 工厂的配置 --> 
 <object id="businessDelegateFactory" 
 class="org.springextensions.actionscript.cairngorm.business.BusinessDelegateFactory" 
   scope="singleton"> 
 <property name="service" ref="personInfosService"/> 
 <property name="delegateClass" type="class" 
    value="business.delegates.PersonDelegate"></property> 
 </object> 

 <! — Command 工厂 --> 
 <object id="appAwareCmdFactory"
	 class="commands.commandfactory.ApplicationModelAwareCommandFactory 
 scope="singleton"> 
   // 注入的 model 
 <property name="applicationModel" ref="appModelLocator" /> 
 // 在 command 中注入的 delegate 
 <method-invocation name="addBusinessDelegateFactory"> 
	 <arg> 
 <ref>businessDelegateFactory</ref> 
	 </arg> 
	 <arg> 
	 <array> 
	 value type="Class">commands.LoadPersonCommand</value> 
	 </array> 
	 </arg> 
 </method-invocation>
 </object> 
 </objects>

创建 MyModelLocator.as 文件,用于注入 model 实例。

清单 20. MyModelLocator.as
 public class MyModelLocator extends EventDispatcher implements IModelLocator, 
      IPeopleModel 
 { 
 public function MyModelLocator() 
 { 
 } 

 public function get personInfos():ArrayCollection 
 { 
 return _personInfos; 
 } 

 public function set personInfos(value:ArrayCollection):void 
 { 
 _personInfos = value; 
 } 
 private var _personInfos:ArrayCollection = new ArrayCollection();
 }

创建 Command Factory 文件,用于动态创建 Command,并将 model 以及 delegate 注入到 Command 中。

清单 21. ApplicationModelAwareCommandFactory.as
 public class ApplicationModelAwareCommandFactory extends ResponderCommandFactory 
        implements ICommandFactory, IApplicationModelAware 
 { 
 private var _applicationModel:IPeopleModel; 

 public function ApplicationModelAwareCommandFactory() { 
	 uper(); 
 } 
 //method in ICommandFactory, the result of this method determine 
 //whether the requested command can be created 
 override public function canCreate(clazz:Class):Boolean 
 { 
    	 if (ClassUtils.isSubclassOf(clazz, CommandBase)) { 
           	 return super.canCreate(clazz); 
   } 
     return false; 			
 } 

 //method in ICommandFactory, used to create command 
 override  public function createCommand(clazz:Class):ICommand 
 { 
	 var result:CommandBase = super.createCommand(clazz) as CommandBase; 
	 result.applicationModel = _applicationModel; 
	 return result;     	       	
 } 
		
 public function set applicationModel(value:IPeopleModel):void 
 { 
 applicationModel = value; 
 } 
 }

创建具体的 command 子类,用于处理具体的业务逻辑。

清单 22. LoadPersonCommand.as
 public class LoadPersonCommand extends CommandBase 
 { 
 public function LoadPersonCommand() 
 { 
 super(); 
 } 

 override public function execute(event:CairngormEvent):void 
 { 
 // 获得注入的 delegate 对象
 super.execute(event); 
 IPersonDelegate(this.businessDelegate).getPersonInfos(); 
 } 
  // 成功回调函数
 override public function result(data:Object):void 
 { 
 //httpservice 接受返回的数据
 } 
   // 失败回调函数
 override public function fault(data:Object):void 
 { 
 Alert.show("load people info failed"); 
 } 
 }

创建具体的 delegate 类用于处理具体的业务逻辑。

清单 23. PersonDelegate
 public class PersonDelegate extends AbstractBusinessDelegate implements IPersonDelegate 
 { 

 public function PersonDelegate(service:* = null,responder:IResponder = null) 
 { 
 super(service, responder); 
 } 

 // 发送请求
 public function getPersonInfos():void 
 { 
 //send request 
 var token:AsyncToken = this.service.send(); 
 token.addResponder(this.responder); 
 } 
 }
图 3. 示例程序结构:
图 3. 示例程序结构:
图 4. 运行结果
图 4. 运行结果

具体实现细节请读者参考代码示例,这里仅仅实现了加载数据和添加数据的功能,删除和修改功能留给读者自己去实现。


结束语

本文对 Flex IOC 框架 Spring Actionscript 如何与 Cairngorm MVC 框架结合到一起做了一个细致的介绍,当然还有一些细节问题值得继续研究,相信通过本文的介绍,可以帮助您更好的掌握这两种框架,从而在 Flex 应用开发中充分发挥它们带给我们的优点。


所需软件


下载

描述名字大小
示例代码IntegrateCairngormAndSpringactionscript.zip1236KB

参考资料

学习

讨论

  • 加入 developerWorks 中文社区。查看开发人员推动的博客、论坛、组和维基,并与其他 developerWorks 用户交流。

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Web development
ArticleID=681042
ArticleTitle=Spring Actionscript IOC 框架与 Flex Cairngorm MVC 应用开发的整合
publish-date=06162011