Spring Actionscript at Devoxx


Published on

Spring ActionScript introduction as presented at the Devoxx conference 2009.

Published in: Technology
1 Comment
No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Spring Actionscript at Devoxx

  1. 1. Spring ActionScript<br />byChristopheHerreman<br />Flex Consultant at Boulevart<br />
  2. 2. Overall presentation<br />Introduction to Spring ActionScript:<br />whatit does and<br />howyou benefit fromusingit<br />
  3. 3. Agenda<br />What is Spring ActionScript<br />The IoC container<br />Configuration<br />MVC Architecture<br />Demo<br />Q&A<br />
  4. 4. Speaker’squalifications<br />CertifiedAdobeFlex & AIR expert<br />10 yearsplayingwith Flash technology<br />Founder and leaddeveloper of AS3Commons & Spring ActionScript<br />Tech reviewerforFoED/Apress<br />
  5. 5. What is Spring ActionScript(1/2)<br />Inversion of Control (IoC) forActionScript 3.0<br />Flash/Flex/AIR/Pure AS3<br />IoC container<br />MVC?<br />
  6. 6. What is Spring ActionScript(2/2)<br />Started as anin-houselibrary<br />Formerlyknown as the Pranaframework<br />Incubated as a Spring Extension project<br />Upcoming release 0.9<br />AS3Commons: Lang, Logging, Reflect, …<br />
  7. 7. The IoC Container (1/3)<br />= Object Factory<br />Creates and assembles objects<br />Centralizeddependency management<br />Spring AS: configuration via XML or MXML<br />
  8. 8. The IoC Container (2/3)<br />Object (bean): object managed and/orcreatedby the container<br />Object Factory: factorythatcreates and managesobjects<br />factory.getObject(“myObject”)<br />Object Definition: blueprintforan object<br />Application Context: smarter Object Factory<br />
  9. 9. The IoC Container (3/3)<br />Object Scopes<br />Singleton: onlyoneinstance in the container<br />Notlinked to the Singleton Design Pattern<br />The default scope<br />factory.getObject(“obj”) == factory.getObject(“obj”)<br />Prototype: newinstancecreatedoneachrequest<br />factory.getObject(“obj”) != factory.getObject(“obj”)<br />
  10. 10. Configuration(1/9)<br />MXML Configuration<br />// AppContext.mxml file, compiledinto the application<br />&lt;Objects&gt;<br /> &lt;app:ApplicationModelid=“appModel” /&gt;<br /> &lt;app:ApplicationControllerid=“appController” applicationModel=“{appModel}”/&gt;<br />&lt;/Objects&gt;<br />
  11. 11. Configuration(2/9)<br />MXML Configuration: loading<br />varcontext:MXMLApplicationContext = newMXMLApplicationContext();<br />context.addConfig(AppContext);<br />context.addEventListener(Event.COMPLETE, context_completeHandler);<br />context.load();<br />function context_completeHandler(event:Event):void {<br />varappModel:ApplicationModel = context.getObject(“appModel”);<br />varappController:ApplicationController = context.getObject(“appController”);<br />}<br />
  12. 12. Configuration(3/9)<br />MXML Configuration: alternativeapproach<br />// AppContext.mxml file, compiledinto the application<br />&lt;Objects&gt;<br /> &lt;Object id=“appModel” clazz=“{ApplicationModel}”/&gt;<br /> &lt;Object id=“appController” clazz=“{ApplicationController}”&gt;<br /> &lt;Property name=“applicationModel” ref=“appModel”/&gt;<br /> &lt;/Object&gt;<br />&lt;/objects&gt;<br />
  13. 13. Configuration(4/9)<br />MXML Configuration: pros<br />Editor support<br />Simple to use<br />
  14. 14. Configuration(5/9)<br />MXML Configuration: cons<br />Compiledinto the application<br />Explicitdeclaration: limited to singletons, noexternalreferences, no prototypes -&gt; use Spring AS MXML dialect<br />
  15. 15. Configuration(6/9)<br />XML Configuration<br />// externalcontext.xml, loadedonapplicationstartup<br />&lt;objects&gt;<br /> &lt;object id=“appModel” class=“com.domain.app.ApplicationModel”/&gt;<br /> &lt;object id=“appController” class=“com.domain.app.ApplicationController”&gt;<br /> &lt;property name=“applicationModel” ref=“appModel”/&gt;<br /> &lt;/object&gt;<br />&lt;/objects&gt;<br />
  16. 16. Configuration(7/9)<br />XML Configuration: loading<br />varcontext:XMLApplicationContext = newXMLApplicationContext();<br />context.addConfigLocation(“context.xml”);<br />context.addEventListener(Event.COMPLETE, context_completeHandler);<br />context.load();<br />function context_completeHandler(event:Event):void {<br /> var appModel:ApplicationModel = context.getObject(“appModel”);<br /> var appController:ApplicationController = context.getObject(“appController”);<br />}<br />
  17. 17. Configuration(8/9)<br />XML Configuration: pros<br />Richer dialect than MXML config<br />Usablefornon-Flexprojects<br />No need to recompile (in some cases)<br />Familiar to Spring Java users<br />
  18. 18. Configuration(9/9)<br />XML Configuration: cons<br />Classes need to becompiledinto the app, noclassloading (!)<br />No editor support, only XSD<br />
  19. 19. MVC Architecture(1/2)<br />No realprescriptivearchitecture<br />Do youreallyneedone?<br />Rollyourownbecauseone does NOT fit all<br />Many MVC architectures out there:<br />Cairngorm, PureMVC, Mate, …<br />… Spring AS wants to support them<br />
  20. 20. MVC Architecture(2/2)<br />Spring AS MVC ingredients<br />Operation API <br />Event Bus<br />Autowiring<br />Recommendations<br />Presentation Model (Fowler)<br />LayeredArchitecture (DDD – Evans)<br />
  21. 21. The Operation API (1/7)<br />Asynchronousbehavior in Flash Player: loadingexternal resources, RMI, sqlite, Webservices, HTTPServices, …<br />No threading API<br />Many different APIs: AsyncToken, Responders, Callbacks, Events… we need a unifiedapproach!<br />
  22. 22. The Operation API (2/7)<br />Problem: a user repository (or service)<br />interface IUserRepository {<br />functiongetUser(id:int): ???<br />}<br />What does the getUsermethod return? AsyncToken (Flex/RemoteObject), User (In memory), void (events)<br />
  23. 23. The Operation API (3/7)<br />Spring AS solution: return a IOperation<br />interface IUserRepository {<br />functiongetUser(id:int):IOperation;<br />}<br />Cannowbeused in anyActionScript 3 context and easilymockedfortesting<br />
  24. 24. The Operation API (4/7)<br />In Spring AS, an “operation” is used to indicateanasynchronousexecution<br />IOperation interface with “complete” and “error” events<br />IProgressOperationwith “progress” event<br />OperationQueuebundlesoperations (a compositeoperation)<br />
  25. 25. The Operation API (5/7)<br />Defininganoperation:<br />publicclassGetUserOperationextendsAbstractOperation {<br />functionGetUserOperation(remoteObject:RemoteObject, id:String) {<br />vartoken:AsyncToken = remoteObject.getUser(id);<br />token.addResponder(newResponder(resultHandler, faultHandler));<br /> }<br /> private functionresultHandler(event:ResultEvent):void {<br />dispatchCompleteEvent(User(event.result));<br /> }<br /> private functionfaultHandler(event:FaultEvent):void {<br />dispatchErrorEvent(event.fault);<br /> }<br />}<br />
  26. 26. The Operation API (6/7)<br />Usage:<br />varoperation:IOperation = newGetUserOperation(remoteObject, 13);<br />operation.addCompleteListener(function(event:OperationEvent):void {<br />varuser:User = event.result;<br />});<br />operation.addErrorListener(function(event:OperationEvent):void {<br />Alert.show(event.error, “Error”);<br />});<br />
  27. 27. The Operation API (7/7)<br />A progressoperation:<br />varoperation:IOperation = newSomeProgressOperation(param1, param2);<br />operation.addCompleteListener(function(event:OperationEvent):void {<br />});<br />operation.addErrorListener(function(event:OperationEvent):void {<br />});<br />operation.addProgressListener(function(event:OperationEvent):void {<br /> var op:IProgressOperation = IProgressOperation(event.operation);<br />trace(“Progress:” + op.progress + “, total: “ + op.total);<br />});<br />
  28. 28. The Event Bus (1/3)<br />Publish/subscribeevent system<br />Usedforglobalapplicationevents<br />Promotesloosecoupling<br />Works withstandard Flash Events<br />
  29. 29. The Event Bus (2/3)<br />Listening/subscribing to events:<br />// listen for all events<br />EventBus.addListener(listener:IEventBusListener);<br />functiononEvent(event:Event):void {<br />}<br />// listen forspecificevents<br />EventBus.addEventListener(“anEvent”, handler);<br />functionhandler(event:Event):void {<br />}<br />
  30. 30. The Event Bus (3/3)<br />Dispatching/publishingevents:<br />// dispatchstandardevent<br />EventBus.dispatchEvent(newEvent(“someEvent”));<br />// dispatchcustomevent<br />classUserEventextendsEvent {<br /> ... <br />}<br />EventBus.dispatchEvent(newUserEvent(UserEvent.DELETE, user));<br />
  31. 31. Autowiring(1/2)<br />Auto DependencyInjection via metadata<br />Autowireby type, name, constructor, autodetect<br />Works forobjectsmanagedby the container and for view components<br />Be careful: magic happens, noexplicitconfiguration<br />
  32. 32. Autowiring(2/2)<br />Annotate a propertywith [Autowired]<br />classUserController {<br /> [Autowired]<br /> public var userRepository:IUserRepository;<br />}<br />[Autowired(name=“myObject“, property=“prop”)]<br />
  33. 33. Summary<br />Dependency Management<br />Loosecoupling, type to interfaces<br />Usewithotherframeworks<br />Spring mentality: provide choice<br />Promote best practices<br />
  34. 34. DEMO<br />A sample application<br />
  35. 35. Thanksforyourattention!<br />www.herrodius.com<br />info@herrodius.com<br />www.springactionscript.org<br />www.as3commons.org<br />