Spring ActionScript入门教程(3)-Spring和Cairngorm的结合使用[下]
本文接上一部分继续完成RSS阅读器实例,在上个部分中我们完成了Lib项目的构建,其实已经基本上完成了项目本身的逻辑代码,而在这一部分,我们将把这个Lib引入到IoC框架中,并编写相应的XML配置文件,最终完成装配,形成完整的应用。
Part4 实现主项目SpringActionScriptCairngormDemo
让我们回到SpringActionScriptCairngormDemo,开始完成IoC的注入工作。
4.1 配置编译参数
打开项目属性,在编译参数部分,将项目依赖的SWC文件都设置好,包括两部分:一部分是已经下载到libs目录下的SWC文件,还要把我们上个例子中编译好的SpringActionScriptCairngormDemoLib.swc也配置进去,配置参数应该如下:
-locale en_US -default-background-color #000000 -include-libraries ../libs/spring-actionscript.swc ../libs/spring-actionscript-cairngorm.swc ../libs/as3commons-reflect.swc ../libs/as3commons-lang.swc ../libs/as3commons-logging.swc ../libs/flexunit.swc ../../SpringActionScriptCairngormDemoLib/bin/SpringActionScriptCairngormDemoLib.swc
参见附图:
4.2 写配置XML
在src目录下,创建一个文件夹名为“config”,然后在config下面再创建两个目录,分别是cairngorm和view,第一个目录是为了存放和Cairngorm相关的配置,第二个目录是用于存放跟视图相关的配置。当然这样拆分目录是为了便于区分和维护,实际上你也可以根据需要按照自己的需要拆分目录结构,IoC对此没有硬性要求。
首先我们先来配置Cairngorm的部分,将Cairngorm部分必须的Service,ModelLocator,FrontControler等部分一一做配置。在cairngorm目录下,创建一个XML文件,名为“cairngorm.xml”。输入下面的内容:
<objects> <!--ModelLocator--> <object id="appModelInstance" class="com.riameeting.model.ApplicationModel" factory-method="getInstance" singleton="true"> <property name="feedURL" value="http://www.riameeting.com/rss.xml" /> </object> <!--Service Locator--> <object id="serviceLocator" class="org.springextensions.actionscript.cairngorm.business.CairngormServiceLocator" factory-method="getInstance"> <property name="feedService"> <ref>feedService</ref> </property> </object> <object id="feedService" class="mx.rpc.http.HTTPService"> <property name="url" value="http://www.riameeting.com/rss.xml"/> <property name="method" value="GET"/> <property name="useProxy" value="false"/> <property name="resultFormat" value="text"/> </object> <!--Delegate Factory--> <object id="businessDelegateFactory" class="org.springextensions.actionscript.cairngorm.business.BusinessDelegateFactory"> <property name="service" ref="feedService"/> <property name="delegateClass" type="class" value="com.riameeting.business.GetFeedDelegate"></property> </object> <!--FrontControler--> <object id="appAwareCmdFactory" class="com.riameeting.factories.ApplicationModelAwareCommandFactory"> <property name="applicationModel" ref="appModelInstance"/> <method-invocation name="addBusinessDelegateFactory"> <arg> <ref>businessDelegateFactory</ref> </arg> <arg> <array> <value type="Class">com.riameeting.command.GetFeedCommand</value> </array> </arg> </method-invocation> </object> <object id="frontController" class="org.springextensions.actionscript.cairngorm.control.CairngormFrontController"> <constructor-arg> <object> <property name="getFeedEvent" value="GetFeedCommand"/> </object> </constructor-arg> <constructor-arg value="com.riameeting.command"/> <method-invocation name="addCommandFactory"> <arg><ref>appAwareCmdFactory</ref></arg> </method-invocation> </object> </objects>
可以看到主体配置分为4个部分:
- ModelLocator - 对应在Lib中创建的ApplicationModel,在此创建一个Model的实例
- Service Locator - 先创建一个ID为“feedService”的HTTPService,然后创建一个ID为“serviceLocator”的Service Locator,将feedService引入进去
- Delegate Factory - 我们通过配置代理工厂,将第二部分的服务注入到代理中去,这样代理就具备了通过自身调用服务的能力,而不需要同外部服务产生直接的依赖
- FrontControler - 首先我们配置工厂类ApplicationModelAwareCommandFactory,将Model注入到Command中去。然后创建一个前端控制器“frontController”,将事件与命令之间建立映射。
然后我们来创建一个关于视图的配置文件,定义界面上都显示什么样的组件,在view下面创建一个XML文件,名为“global.xml”,然后输入下面的内容:
<objects> <object id="searchForm" class="com.riameeting.view.AddressBar"> <property name="model" ref="appModelInstance"/> <property name="x" value="10"/> <property name="y" value="10"/> </object> <!--<object id="searchResult" class="com.riameeting.view.SearchResultWithTable">--> <object id="searchResult" class="com.riameeting.view.SearchResult"> <property name="model" ref="appModelInstance"/> <property name="x" value="10"/> <property name="y" value="60"/> </object> <object class="com.riameeting.utils.ApplicationViewAssembler" init-method="init"> <property name="elements"> <value> <array> <ref>searchForm</ref> <ref>searchResult</ref> </array> </value> </property> </object> </objects>
你可以看到视图方面配置了三个部分,第一个对应我们在Lib中定义的搜索组件,ID是searchForm,第二个是用于显示Feed内容的列表组件,ID是searchResult,而第三个配置只是为了使用工具类将前两个组件添加到显示列表中。并且为每一个视图组件,都指定了Model的引用,就是我们在Cairngom.xml中配置好的Model。
然后我们定义一个主体的XML,在config下面创建一个名为“”的XML文件,引入上面创建的两个XML,内容如下:
<?xml version="1.0" encoding="UTF-8"?> <objects> <import file="view/global.xml"/> <import file="cairngorm/cairngorm.xml"/> </objects>
4.3 实现IoC容器载入
打开SpringActionScriptCairngormDemo.mxml,建立一个代码块,声明一下IoC容器,载入配置文件,代码如下:
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="init()" layout="absolute" width="420" height="480" viewSourceURL="srcview/index.html"> <mx:Script> <![CDATA[ import org.springextensions.actionscript.context.support.FlexXMLApplicationContext; private function init():void { var context:FlexXMLApplicationContext = new FlexXMLApplicationContext(appContextPath); context.load(); } trace("loaded"); } ]]> </mx:Script> </mx:Application>
编译并运行项目,就可以看到运行结果了。
演示地址:
http://www.riameeting.com/examples/SpringASCairngormDemo/SpringActionScriptCairngormDemo.html
提示:你可以在Demo上点击右键查看源码。
附件中是两个项目的源码下载。


.gif)
.gif)




.gif)
为什么要独立创建lib项目呢?
首先,谢谢楼主的教程,很详细,很容易入门。其次我在运行这个demo的时候,也出现了点小问题:
1.新建的lib工程时,mxml文件在flex标准工程中不可以inport.dubug会出现找不到类的错误。但是楼主的是可以的,原因我锁定在lib项目上,可是没找到具体是为什么!
2.为何要分成两个项目呢?这是spring机制必须 还是楼主刻意为之。
3.我尝试合二为一时,发现找不到类错误。
4.楼主讲解了程序的流程,但是没有讲解为何这么运行,即程序从哪里启动,简单讲 就是程序代码运行的流程。我初学,所以很多不懂。
5.我又在想 caringorm框架 内部耦合较高,spring是用来解耦,所以我想修改修改这些代码,是否能够以更少的xml配置量达到解耦的要求。
如果楼主或是路人阅过此留言,期待建议。
有这方面的爱好者 欢迎切磋 email: wushexin2006@126.com
自己对自己的回复,不足之处,见谅
呵呵 这是我自己对自己的回复。其实上叙所有的问题 要是可以合二为一那就什么都解决了。今天看了一天的英文文档,终于找到了一个解。可能不是最好的解,但也确实暂时解决了这个问题。
我的思路也就是将合二为一。在楼主的代码中 将demolib项目中src下的源代码 拷贝到 demo的src下,将demo的编译时参数改为
-locale en_US -default-background-color #000000 -include-libraries ../libs/spring-actionscript.swc ../libs/as3commons-reflect.swc ../libs/as3commons-lang.swc ../libs/as3commons-logging.swc ../libs/flexunit.swc
如果此时dubug,还是会发现找不到xxx类。原因是swc文件找不到类,因为没有在任何时候告诉他xxx类已经编译进来了。原本楼主的解决方案也是很好的。但是我这里的解决方案是 新增一个配置文件。ClassReferences.properties 放到src目录下就好了。文件的中内容如下:
GetFeedCommand = ClassReference("com.riameeting.command.GetFeedCommand")
ApplicationModel = ClassReference("com.riameeting.model.ApplicationModel")
AddressBar = ClassReference("com.riameeting.view.AddressBar")
SearchResult = ClassReference("com.riameeting.view.SearchResult")
ApplicationViewAssembler = ClassReference("com.riameeting.utils.ApplicationViewAssembler")
ApplicationModelAwareCommandFactory = ClassReference("com.riameeting.factories.ApplicationModelAwareCommandFactory")
GetFeedDelegate = ClassReference("com.riameeting.business.GetFeedDelegate")
其次要在主应用程序mxml中加入一个变量定义。下面修改后的 SpringActionScriptCairngormDemo.mxml
width="420" height="480" viewSourceURL="srcview/index.html">
import mx.resources.ResourceBundle;
import org.springextensions.actionscript.context.support.FlexXMLApplicationContext;
[ResourceBundle("ClassReferences")]
private var springClassRefs:ResourceBundle;
private function init():void {
var appContextPath:String = "config/application_context.xml";
var context:FlexXMLApplicationContext = new FlexXMLApplicationContext(appContextPath);
context.addEventListener(Event.COMPLETE,onIoCLoadComplete);
context.load();
}
private function onIoCLoadComplete(e:Event):void {
trace("loaded");
}
]]>
至此 运行程序 将和楼主的一样。这是提供了一种解决方案,如果哪位大师有更好的解法,我们洗耳恭听。还有楼主说,希望大家多社区交流,将riameeting发扬光大。
分成两个项目是为了
分成两个项目是为了方便把所有的类编译到主工程中,这个倒不是Spring的强制要求,只要你能保证主项目在使用IoC的时候,能包含所需要的类即可。因为在Flex中使用IoC很容易出现这样的问题:我写了一个类,只会在IoC装配的时候会使用到,而没有在实际的代码中引用到,这样Flex编译的时候会把这个类排除在外,会导致运行时找不到所需的类。
关于流程,简单来讲,要分成两个方面来看:IoC部分,应用在加载配置的XML完毕之后,就由IoC容器开始装配所有配置的Bean,Cairngorm部分,我们是用事件来驱动,所有的执行动作会映射为一个命令的实例来运行
工厂的配置
呵呵 程序运行的流程我已经明白了 谢谢楼主热心释疑!现在还有一点问题是配置中的 工厂配置我有点不好理解。配置工厂有何用?而又是如何配置的呢?
及下面代码的中的第一个object配置
businessDelegateFactory
代码应该是这段
businessDelegateFactory
关于FLEX Liberary project的使用
你好,这个sample工程把很多具体实现的代码都放在liberary project里面生成SWC文件,个人认为这样做有待商榷,如果业务变更或者增加一些功能岂不是要重新生成SWC文件,从而影响rsl的效率.使用Lib工程是不是应该把共同不经常变更的东西打包作为Lib使用呢?
您好,您的想法是正
您好,您的想法是正确的,这个例子足够简单,所以我没有拆分,实际上您可以根据需要拆分出不同的SWC,比如公用的类是一个SWC,而其它部分再作为其它的SWC存在,或者使用RSL,只要满足IOC的前提(依赖的类必须可以找到)就可以。
我直接引用了网上编译的lib也不行啊!
我的开发环境 myeclipse 6.5+flex3.2 插件版!
我flexbuid3.0 直接引用网上代码呢!只能出现空白窗口,真晕
我编译过是可以的,
我编译过是可以的,或许你该进Debug模式仔细看看,SpringActionScript的SWC似乎有些问题,有警告信息输出,不知大家遇到过没有
Debug无法跟踪
有qq吗能联过来帮忙看看吗?我qq:914440226
发表新评论