First, this framework rocks! 3 Thumbs up for porting this over to AS
from the Java world!
I've been working on a pretty large Flex + Java stack with my team for
some time now and I decided to create a tutorial series on it...when I
started I was using SAS 0.7.1 and didn't realize the framework had not
only been adopted by the Spring Community, but was also much farther
along than in it's implementation and had new docs, etc...to that, I
decided to revamp my original Flex + Spring ActionScript ("SAS") +
Cairngorm ("CG") with the new SAS v0.8 and base it on the docs that
explained how to integrate the CG extensions. Here's my current
example with the source exposed -- the accompanying blog post is still
in the works but I wanted to get the SAS Communities take on it --
feel free to rip/slice/dice, whatever, just putting it out there as a
full working example for the community...a starting point if you will.
I provided 2 Login Delegates -- an AS Mock Object Delegate and an XML
Delegate. If you look at the spring-delegates.xml app context file,
you can simply comment/uncomment the desired Delegate Factory and
you're off t the races and running. Now using an AS Mock Obj Del and a
local XML Del doesn't prove much, but if you were to have RemoteObject
Dels in the mix too, then theoretically you could start creating the
app as soon as you perform concrete service identification and
specifications and the Flex dev doesn't have to wait for the server-
side guys to create (even mocked up) RO services.
Also, one of the guys on my team asked why I bother injecting the
Model Locator ("ML") since there's only one in the app...well, in an
effort to further decouple the app, if you were to create say another
hardcoded, AS Mock Object ML then you can start developing the views
as soon as your client-side domain model has been established...and
even better than that is that you can now test each layer of your
application completely independent of whether or not others work or
are ready for primetime -- would be really nice to test a view's data
bindings to the ML without having to recompile the app with one
hardcoded ML and one real ML that has to ge data from the Commands.
Beautiful.
Here's a couple things that I noticed while building the app that
didn't quite add up:
1) AutoWiring MXML view components didn't seem to work for me unless I
added the components to the stage after (and only after) all the app
context files had been loaded (parsed, objects instantiated and
cached, etc). You'll notice in my main, Application class that I have
my MainView in MXML commented out and that I'm adding it to the stage
after the app context files load. Maybe I missed something to make
this work correctly -- download the app and give it a look.
2) The Service Locator ("SL") seems superfluous, as the delegates are
injecting the serfvices based on the references for the actual service
object definitions. If you think about it, with SAS, a spring-
services.xml application context file "is" the SL. Thoughts?
3) When I first created the example, I made it a combined Flex + Java
project in WTP, so naturally my Flex app ran on a web server...uh oh,
now my XML app context files get cached...I saw that you guys removed
the lined to kill caching with the random number b/c this didn't seem
to work for Flex project's not running on a web server -- that might
be IE only to be honest. Firefox works fine with this. Anyways, I
added that line back in when laoding the XML files to fix the problem:
var killCaching:String = "";
killCaching += ("?" + Math.round(Math.random() * 1000000));
and then appended that to the end of each app context file URL.
Perhaps you can just put in an additional param in the constructor for
the AppContextLoader that allows devs to say yes, add kill cache or
not? You can also do some tricks to determine if the app is running on
a web server or not inside the class so it's not up to the dev.
4) I believe many have already commented on this, but there seems to
be number of stack traces when the app context is first firing up,
although they're not real errs and don't cause the app to bomb -- most
of them take this form:
Fri Jun 26 16:21:13 GMT-0400 2009 [DEBUG] org.as3commons.reflect.Type
- Error while instantiating class [class Event] with null arguments in
order to retrieve constructor argument types: TypeError, 2007
Message: Error #2007: Parameter type must be non-null.
Stack trace: TypeError: Error #2007: Parameter type must be non-null.
at flash.events::Event()
at org.as3commons.lang::ClassUtils$/newInstance()[C:\workspace
\as3commons\as3-commons-lang\src\main\actionscript\org\as3commons\lang
\ClassUtils.as:316]
at org.as3commons.reflect::Type$/_getTypeDescription()[C:\workspace
\as3commons\as3-commons-reflect\src\main\actionscript\org\as3commons
\reflect\Type.as:362]
at org.as3commons.reflect::Type$/forClass()[C:\workspace\as3commons
\as3-commons-reflect\src\main\actionscript\org\as3commons\reflect
\Type.as:172]
at org.as3commons.reflect::Type$/forName()[C:\workspace\as3commons
\as3-commons-reflect\src\main\actionscript\org\as3commons\reflect
\Type.as:143]
at TypeXmlParser$/parseParameters()[C:\workspace\as3commons\as3-
commons-reflect\src\main\actionscript\org\as3commons\reflect\Type.as:
442]
at TypeXmlParser$/parseMethodsByModifier()[C:\workspace\as3commons
\as3-commons-reflect\src\main\actionscript\org\as3commons\reflect
\Type.as:430]
at TypeXmlParser$/parseMethods()[C:\workspace\as3commons\as3-commons-
reflect\src\main\actionscript\org\as3commons\reflect\Type.as:405]
at org.as3commons.reflect::Type$/forClass()[C:\workspace\as3commons
\as3-commons-reflect\src\main\actionscript\org\as3commons\reflect
\Type.as:181]
at org.as3commons.reflect::Type$/forName()[C:\workspace\as3commons
\as3-commons-reflect\src\main\actionscript\org\as3commons\reflect
\Type.as:143]
at TypeXmlParser$/parseParameters()[C:\workspace\as3commons\as3-
commons-reflect\src\main\actionscript\org\as3commons\reflect\Type.as:
442]
at TypeXmlParser$/parseConstructor()[C:\workspace\as3commons\as3-
commons-reflect\src\main\actionscript\org\as3commons\reflect\Type.as:
396]
at org.as3commons.reflect::Type$/forClass()[C:\workspace\as3commons
\as3-commons-reflect\src\main\actionscript\org\as3commons\reflect
\Type.as:179]
at
org.springextensions.actionscript.ioc.factory.support::AbstractObjectFactory/
getObject()[/Users/brianmriley/projects/spring-hibernate/workspaces/
emp-mgmt-console/SpringActionScript/trunk/core/src/main/actionscript/
org/springextensions/actionscript/ioc/factory/support/
AbstractObjectFactory.as:193]
at
org.springextensions.actionscript.ioc.factory.support::DefaultListableObjectFactory/
preInstantiateSingletons()[/Users/brianmriley/projects/spring-
hibernate/workspaces/emp-mgmt-console/SpringActionScript/trunk/core/
src/main/actionscript/org/springextensions/actionscript/ioc/factory/
support/DefaultListableObjectFactory.as:144]
at
org.springextensions.actionscript.context.support::XMLApplicationContext/
afterParse()[/Users/brianmriley/projects/spring-hibernate/workspaces/
emp-mgmt-console/SpringActionScript/trunk/core/src/main/actionscript/
org/springextensions/actionscript/context/support/
XMLApplicationContext.as:171]
at
org.springextensions.actionscript.ioc.factory.xml::XMLObjectFactory/
_doParse()[/Users/brianmriley/projects/spring-hibernate/workspaces/emp-
mgmt-console/SpringActionScript/trunk/core/src/main/actionscript/org/
springextensions/actionscript/ioc/factory/xml/XMLObjectFactory.as:346]
at
org.springextensions.actionscript.ioc.factory.xml::XMLObjectFactory/
_loadNextProperties()[/Users/brianmriley/projects/spring-hibernate/
workspaces/emp-mgmt-console/SpringActionScript/trunk/core/src/main/
actionscript/org/springextensions/actionscript/ioc/factory/xml/
XMLObjectFactory.as:317]
at
org.springextensions.actionscript.ioc.factory.xml::XMLObjectFactory/
_loadNextConfigLocation()[/Users/brianmriley/projects/spring-hibernate/
workspaces/emp-mgmt-console/SpringActionScript/trunk/core/src/main/
actionscript/org/springextensions/actionscript/ioc/factory/xml/
XMLObjectFactory.as:294]
at
org.springextensions.actionscript.ioc.factory.xml::XMLObjectFactory/
_onLoaderComplete()[/Users/brianmriley/projects/spring-hibernate/
workspaces/emp-mgmt-console/SpringActionScript/trunk/core/src/main/
actionscript/org/springextensions/actionscript/ioc/factory/xml/
XMLObjectFactory.as:246]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at flash.net::URLLoader/onComplete()
You can view the completed application here with view source enabled:
http://www.webappsolution.com/flex/blog/examples/emp-mgmt-console-5/EmployeeManagementConsole5.html
http://www.webappsolution.com/flex/blog/examples/emp-mgmt-console-5/srcview/index.html
The frameworks rocks and I'm a huge fan for many reasons! Keep it up
and I'll do my best to keep digging into the new versions and helping
out where possible.
You guys rock!
-riley
http://www.webappsolution.com/
http://www.webappsolution.com/wordpress/