由於上次稍微玩了一下 Robotlegs 依賴注入(DI) 主導的 MVC 框架,而著名也使用依賴注入的 Java / Java EE 的 Spring framework 出了 for ActionScript 的版本,剛好在最近 Spring ActionScript 1.0 正式 release 了(想了解 Spring 是啥咪東東的話請自行找 google 大神),這個版本除了基本框架外,也包含了 Cairngorm 與 PureMVC 的外掛...想當然耳,就拿來測試一下用在 PureMVC 內的感覺囉!!
參考了官方範例 中 PureMVC 唯二的範例原始檔,以下使用的是「設定檔依賴注入 facade 透過 addConfigSource() 的方式來 init 」:(其實除了 embed 外,都是外部載入)
Online Demo with source code
工作環境:FlashBuilder, Flex SDK4
Spring 的 injection 並不像 Robotlegs 直接來個 [Inject] metadata 的自動化那樣方便,但是其冷血度(檔案的鬆偶程度)更勝後者!如果你要使用設定檔(applicationContext.xml) 來做注入的話,準備工作就挺多的...XD
application-context.xml :
程式內用到的 Ioc 系列 class 的 getConfigName() 就是指 object tag id。
設定依賴注入的 setter name, ref 為 object tag 的 id。
其他 xml schemas 設定請看官網教學文件。
LoaderListCommand 實作:
接下來在 compiler config 的 xml 中列出所有要預先打包的 classes:
configurationClassesCompilerConfig.xml
然後:在 Project/properties 中設定 Additional Compiler Arguments:
如下圖位置:
基本上的設定就是如同上面步驟。
最後,範例檔內有兩個外部 list data xml,你可以試著修改 application-context.xml 中的 serviceUrl value to "List2.xml"
重新 reload 後你會發現,這時候 LoaderDelegate 所載入的資料就是 List2.xml 囉!如果你預先將同類可置換的 class 打包起來,你也可以在 runtime 的時候修改 application-context object class ref,這就是 Ioc 強大的地方囉!
結語:
以上僅說明到 PureMVC with Spring extensions 部分,其餘 Spring ActionScript Core API 請自行上官網學習囉!
BTW...對它不熟的朋友們請勿輕易服用拿真正的專案去實作捏...XD
參考了官方範例 中 PureMVC 唯二的範例原始檔,以下使用的是「設定檔依賴注入 facade 透過 addConfigSource() 的方式來 init 」:(其實除了 embed 外,都是外部載入)
Online Demo with source code
工作環境:FlashBuilder, Flex SDK4
- 請下載 PureMVC Standard 版本
- 再下載 Spring ActionScript 最新版本後,除了 spring-actionscript-cairngorm 不需要外,都放到 /src 下(記得只需要 org 開始...),也別忘了lib 內的 swc 檔 copy 到 /libs 下
Spring 的 injection 並不像 Robotlegs 直接來個 [Inject] metadata 的自動化那樣方便,但是其冷血度(檔案的鬆偶程度)更勝後者!如果你要使用設定檔(applicationContext.xml) 來做注入的話,準備工作就挺多的...XD
- 依照 applicationContext.xml 內設定的方式分別寫入 constructor 或者是 setter 依賴注入(本範例統一使用 setter injection)
- 為了跟大家都沒關係所以都使用 interface 來處理,所以你會在範例中發現大家都有介面...(並沒有真的研究過 Spring,也許還有其他作法)
- 準備 compiler 時候要用的 classe。由於在 setter, getter 的寫法上都使用 interface,所以真正用到的 class 需要預先在輸出階段就打包到程式內。
- 基本上 PureMVC 類 class 都改為繼承自 IocSimpleCommand, IocFacade, IcoMediator and IocProxy.
application-context.xml :
程式內用到的 Ioc 系列 class 的 getConfigName() 就是指 object tag id。
........
<object id="updateListCommand" class="com.mvc.control.UpdateListCommand">
<property name="listProxy" ref="listProxy"/>
</object>
<object id="listProxy" class="com.mvc.model.impl.ListProxy">
<property name="loaderDelegate" ref="loaderDelegate"/>
</object>
........
設定依賴注入的 setter name, ref 為 object tag 的 id。
其他 xml schemas 設定請看官網教學文件。
<property name="listProxy" ref="listProxy"/>
LoaderListCommand 實作:
........
public class UpdateListCommand extends IocSimpleCommand
{
private var m_proxy:IListProxy;
public function UpdateListCommand()
{
super();
}
// setter injection
public function set listProxy( proxy:IListProxy ):void{
m_proxy = proxy;
}
public function get listProxy():IListProxy{
return m_proxy;
}
...........
接下來在 compiler config 的 xml 中列出所有要預先打包的 classes:
configurationClassesCompilerConfig.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<flex-config>
<includes>
<symbol>com.mvc.control.StartUpCommand</symbol>
<symbol>com.mvc.control.UpdateListCommand</symbol>
<symbol>com.mvc.view.ListMediator</symbol>
<symbol>com.mvc.model.impl.ListProxy</symbol>
<symbol>com.mvc.delegate.impl.LoaderDelegate</symbol>
</includes>
</flex-config>
然後:在 Project/properties 中設定 Additional Compiler Arguments:
-load-config+=config/configurationClassesCompilerConfig.xml
如下圖位置:
基本上的設定就是如同上面步驟。
最後,範例檔內有兩個外部 list data xml,你可以試著修改 application-context.xml 中的 serviceUrl value to "List2.xml"
<object id="loaderDelegate" class="com.mvc.delegate.impl.LoaderDelegate">
<property name="serviceUrl" value="List2.xml"/>
</object>
重新 reload 後你會發現,這時候 LoaderDelegate 所載入的資料就是 List2.xml 囉!如果你預先將同類可置換的 class 打包起來,你也可以在 runtime 的時候修改 application-context object class ref,這就是 Ioc 強大的地方囉!
結語:
以上僅說明到 PureMVC with Spring extensions 部分,其餘 Spring ActionScript Core API 請自行上官網學習囉!
BTW...對它不熟的朋友們請勿輕易服用拿真正的專案去實作捏...XD
spring有一個基本假設,就是可以透過reflection動態載入程式碼,這在其他的主要程式語言(java, c#, 甚至 vb.net)都是成立的。
ReplyDelete但偏偏reflection是flash的弱項,另外就是寫loadee(被載入的程式碼檔案),需要手動exclude class到讓人瘋狂。所以,現在spring.actionscript使用的這些設定,都是為了能用一個.swf檔案把一切打包,但一開始,這就大大減損了spring的長處(使用config file動態決定程式碼的執行,程式碼散落在各個.dll檔案中,而非compile time就決定)。
而且,我也懷疑在大型計畫下,一個必須用人工維護的20~30k config xml檔案,本身不會引入更多的錯誤。我個人關注過這個計畫很長一陣子(我這兩年都在用spring.net寫asp.net),這不是一個容易使用的library,再加上上面說的種種限制,也因此,我對這個專案一直持保留的態度。
但我是建議大家可以藉這個機會瞭解dependency injection,或是直接看Martin Fowler當初提出這個概念的原文(中文版的連結已經失效很久了,但google應該還找得到):
http://martinfowler.com/articles/injection.html
.swf 檔案與avm,需要一些蠻基本的改變,才能跟spring相處愉快,但那很可能就改變了flash之所以為flash的基本假設:節省檔案大小,因此用不到的,就不會放進.swf檔案中。(silverlight就不是這樣想的,所以,稍微有一點規模的案子,就是一堆.xap檔案會被載入)
後續會如何發展,倒是頗值得關注...
拉丁大講的沒錯,Spring AS3 的版本實在有點麻煩,尤其光手動打包必要的東西這段就很麻煩了,我猜光一般專案那個 config xml 就應該會很可觀。如果真的需要用到 Spring 的話,程式碼就需要如同拉丁大所說的散落在不同的 swf 內才能達到最佳利用(沒辦法...還是要打包...XD )。不過 DI 這個東西是真的可以關注(真的很有趣),也希望 Spring 接下來的版本是更好用的...目前這個版本是有夠囉嗦的啦...
ReplyDeleteBTW 那個 config xml 真的是有麻煩到... = =