Вы находитесь на странице: 1из 158

Spring ActionScript

Reference Documentation
Spring ActionScript: Reference Documentation
1.1
Table of Contents
Preface ............................................................................................................................ vi
I. Getting Started ................................................................................................................ 1
1. Introduction ........................................................................................................... 2
What is Spring Actionscript? ................................................................................ 2
2. The Inversion of Control (IoC) container ..................................................................... 3
Introduction ....................................................................................................... 3
Basics - containers and objects ..................................................................... 3
Dependencies ........................................................................................... 17
Customizing the nature of an object ............................................................. 41
Knowing who you are ............................................................................... 42
Object definition inheritance ....................................................................... 42
Object scopes ........................................................................................... 45
Customizing the nature of an object ............................................................. 47
Container extension points .......................................................................... 48
Controlling collection order ........................................................................ 54
II. APIs and extensions ...................................................................................................... 55
3. Metadata annotations handling ................................................................................. 56
Introduction ..................................................................................................... 56
Controlling the order of IMetadataProcessors ................................................. 57
4. The Operation API ................................................................................................ 58
Introduction ..................................................................................................... 58
Operations, commands, services and tasks ..................................................... 58
5. The EventBus ....................................................................................................... 71
Introduction ..................................................................................................... 71
EventBus listening .................................................................................... 71
EventBus dispatching ................................................................................ 71
EventBus event handling using metadata annotations ....................................... 72
Routing other events through the EventBus ................................................... 73
Metadata driven MVC micro-framework ....................................................... 74
6. The Component scanner and class scanning system ..................................................... 78
Introduction ..................................................................................................... 78
[Component] metadata explained ......................................................................... 78
Injecting constructor arguments ................................................................... 80
Injecting properties .................................................................................... 80
Method invocations ................................................................................... 81
Extending the class scanning system .................................................................... 82
The IClassScanner interface ........................................................................ 82
Controlling the order in which class scanners are executed ................................ 83
7. Testing ................................................................................................................ 84
Introduction ..................................................................................................... 84
Integration Testing ............................................................................................ 84
Overview ................................................................................................. 84
8. Spring Actionscript extensions ................................................................................. 91
Introduction ..................................................................................................... 91
Cairngorm 2 ............................................................................................ 91
PureMVC .............................................................................................. 111
III. Appendixes ............................................................................................................... 122
A. XML Schema-based configuration ......................................................................... 123
Introduction .................................................................................................... 123
XML Schema-based configuration ...................................................................... 123
Referencing the schemas .......................................................................... 123

iii
Spring ActionScript

The util schema .............................................................................................. 124


<util:constant/> ....................................................................................... 124
<util:invoke/> ......................................................................................... 125
The messaging schema ..................................................................................... 125
<messaging:channel-set> .......................................................................... 126
<messaging:channel> ............................................................................... 126
<messaging:abstract-consumer> ................................................................. 126
<messaging:producer> .............................................................................. 127
The RPC schema ............................................................................................ 127
The stage processing schema ............................................................................. 127
<si:genericstageprocessor> ........................................................................ 127
B. Extensible XML authoring .................................................................................... 129
Introduction .................................................................................................... 129
Authoring the schema ...................................................................................... 129
Coding an INamespaceHandler implementation .................................................... 130
Coding an IObjectDefinitionParser implementation ................................................ 131
Registering the handler ..................................................................................... 132
Code generator ............................................................................................... 132
C. Forcing Actionscript class inclusion ....................................................................... 134
Introduction .................................................................................................... 134
Adding an anonymous code block .............................................................. 134
Declaring a list of variables ...................................................................... 134
Using the Frame metadata ........................................................................ 134
Using a resource bundle ........................................................................... 134
Using an ANT task as a prebuilder to generate a compiler config file ................. 135
Using Maven .......................................................................................... 137
IV. Reference ................................................................................................................. 139
9. Configuration reference ........................................................................................ 140
General description .......................................................................................... 140
10. ....................................................................................................................... 151

iv
List of Tables
2.1. The object definition ................................................................................................... 10
2.2. Autowiring modes ...................................................................................................... 26
2.3. Autowiring modes ...................................................................................................... 27
2.4. Object scopes ............................................................................................................. 45

v
Preface
Developing software applications is hard enough even with good tools and technologies. Implementing
applications using platforms which promise everything but turn out to be heavy-weight, hard to control
and not very efficient during the development cycle makes it even harder. Spring Actionscript provides a
full-featured IoC container and several low-level extensions to existing frameworks which can make daily
life for a developer a little easier.

Spring Actionscript is modular, allowing you to use just those parts of it that you need, without having to
bring in the rest. You can use the IoC container, but leave the Cairngorm extensions alone and use your
own solutions instead.

Spring Actionscript aims to be non-obtrusive and not to impose any kind of unnecessary structure to your
application while still promoting best practices in software development.

This document provides a reference guide to Spring Actionscript's features. Since this document is still to
be considered very much work-in-progress, if you have any requests or comments, please post them on
the user mailing list or on the support forums at .

vi
Part I. Getting Started
The basic functionality of the IoC container
Chapter 1. Introduction
What is Spring Actionscript?
Spring ActionScript is an offshoot of the Java-based Spring Framework written in ActionScript 3. It is
targeted for the Flash, Flex and AIR platforms. The framework contains an Inversion of Control Container,
an Operation and Task API, an EventBus, a metadata handling system, extensions for the Cairngorm and
PureMVC frameworks and several other utilities.

2
Chapter 2. The Inversion of Control
(IoC) container
Introduction
This chapter covers the Spring Actionscript Framework's implementation of the Inversion of Control (IoC)
principle.

The and packages provide the basis for the Spring Actionscript Framework's IoC container.

The FlexXMLApplicationContext or XMLApplicationContext are the classes that any programmer


starting out with Spring Actionscript will encounter as the first pieces of code from the framework that they
will need to use. The classes are nearly identical, FlexXMLApplicationContext only adds Flex specific
support, such as for the ArrayCollection.

These classes take care of loading and parsing of a configuration file, after which they are able to instantiate,
assemble and otherwise manage objects.

In this chapter we are going to describe how to set up a configuration file, create an application context
and use it to instantiate objects.

Basics - containers and objects


The objects that are managed by the Spring Actionscript IoC container, and the dependencies between
them, are reflected in the configuration metadata used by a container.

The container
The FlexXMLApplicationContext or XMLApplicationContext classes are the central IoC container
objects in Spring Actionscript. Their responsibilities include instantiating or sourcing application objects,
configuring such objects, and assembling the dependencies between these objects.

They inherit from XMLObjectFactory which allows you to express the objects that compose your
application, and the doubtless rich interdependencies between such objects, in terms of XML. The
XMLObjectFactory takes this XML configuration metadata and uses it to create a fully configured system
or application.

So what does this mean in plain English?

An instance of FlexXMLApplicationContext or XMLApplicationContext can read an XML file containing


a description of the dependencies of your business objects and manage these dependencies. For instance,
do all your business object need a reference to your model? But you want to be certain that they all receive
the same reference without having to depend on a singleton object?

This is where the IoC container comes in.

Configuration metadata
Spring Actionscript supports configurations defined in XML or MXML. When using XML-based
configuration metadata, you write object definitions for those objects that you want the Spring Actionscript
IoC container to manage, and then let the container do its stuff. Spring Actionscript configuration consists
of at least one object definition that the container must manage, but typically there will be more than one
object definition. These object definitions are configured as elements inside a top-level element.

3
The Inversion of
Control (IoC) container

(See Composing MXML based configuration metadata for how to perform this task using MXML instead).

These object definitions correspond to the actual objects that make up your application, they describe how
these objects need to be instantiated and configured.

Find below an example of the basic structure of XML-based configuration metadata.

<?xml version="1.0" encoding="utf-8"?>


<objects xmlns="http://www.springactionscript.org/schema/objects"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springactionscript.org/schema/objects
http://www.springactionscript.org/schema/objects/spring-act

<object id="..." class="...">


<!-- collaborators and configuration for this object go here -->
</object>
<object id="..." class="...">
<!-- collaborators and configuration for this object go here -->
</object>

<!-- more object definitions go here -->


</objects>

Instantiating a container
Instantiating a Spring Actionscript IoC container is straightforward.

var applicationContext:XMLApplicationContext = new XMLApplicationContext();


applicationContext.addConfigLocation("application-context.xml");
applicationContext.addEventListener(Event.COMPLETE, handleComplete);
applicationContext.load();

The application-xml file in the above listing resides either on a remote server or a local file. Depending
on the application in question being a Flex/Flash or AIR application. Either way, the XML file is being
loaded using a URLLoader object. This means that this operation is asynchronous i.e. The application
can't know beforehand when this it is finished. Hence the addEventListener call: once container has fully
loaded the XML file and has successfully parsed it, the complete event is fired and the handleComplete
method will be called.

To avoid hard coding the URL to the configuration file in the application source it is recommended to
pass this a flashvar into the Flex application. These flashvars can be defined in Flex Builder in the HTML
template. This template can be found in the project directory root and is called html-template. In this
directory is resides a file called index.template.html.

Below is an example of how a flashvar defining the application-context.xml location, this example shows
all the code between the <body> tag of the template. The relevant pieces of code have been marked in bold.

<script language="JavaScript" type="text/javascript">


<!--
// Version check for the Flash Player that has the ability to start Player Product
var hasProductInstall = DetectFlashVer(6, 0, 65);

// Version check based upon the values defined in globals


var hasRequestedVersion = DetectFlashVer(requiredMajorVersion, requiredMinorVersion

if ( hasProductInstall && !hasRequestedVersion ) {

4
The Inversion of
Control (IoC) container

// DO NOT MODIFY THE FOLLOWING FOUR LINES


// Location visited after installation is complete if installation is required
var MMPlayerType = (isIE == true) ? "ActiveX" : "PlugIn";
var MMredirectURL = window.location;
document.title = document.title.slice(0, 47) + " - Flash Player Installation";
var MMdoctitle = document.title;

AC_FL_RunContent(
"src", "playerProductInstall",
"FlashVars", "MMredirectURL="+MMredirectURL+'&MMplayerType='+MMPlayerType+'
"width", "${width}",
"height", "${height}",
"align", "middle",
"id", "${application}",
"quality", "high",
"bgcolor", "${bgcolor}",
"name", "${application}",
"allowScriptAccess","sameDomain",
"type", "application/x-shockwave-flash",
"pluginspage", "http://www.adobe.com/go/getflashplayer"
);
} else if (hasRequestedVersion) {
// if we've detected an acceptable version
// embed the Flash Content SWF when all tests are passed
AC_FL_RunContent(
"src", "${swf}",
"FlashVars", "ContextURL=application-context.xml",
"width", "${width}",
"height", "${height}",
"align", "middle",
"id", "${application}",
"quality", "high",
"bgcolor", "${bgcolor}",
"name", "${application}",
"allowScriptAccess","sameDomain",
"type", "application/x-shockwave-flash",
"pluginspage", "http://www.adobe.com/go/getflashplayer"
);
} else { // flash is too old or we can't detect the plugin
var alternateContent = 'Alternate HTML content should be placed here. '
+ 'This content requires the Adobe Flash Player. '
+ '<a href=http://www.adobe.com/go/getflash/>Get Flash</a>';
document.write(alternateContent); // insert non-flash content
}
// -->
</script>
<noscript>
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
id="${application}" width="${width}" height="${height}"
codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swfl
<param name="FlashVars" value="ContextURL=application-context.xml" />
<param name="movie" value="${swf}.swf" />
<param name="quality" value="high" />
<param name="bgcolor" value="${bgcolor}" />

5
The Inversion of
Control (IoC) container

<param name="allowScriptAccess" value="sameDomain" />


<embed src="${swf}.swf" quality="high" bgcolor="${bgcolor}"
width="${width}" height="${height}" name="${application}" align="mi
play="true"
loop="false"
quality="high"
flashvars="ContextURL=application-context.xml"
allowScriptAccess="sameDomain"
type="application/x-shockwave-flash"
pluginspage="http://www.adobe.com/go/getflashplayer">
</embed>
</object>
</noscript>

To access the flashvar parameters add an eventhandler for the preinitialize event in your application, like
so:

addEventListener(FlexEvent.PREINITIALIZE,handlePreInit);

or in MXML:

<mx:Application preinitialize="handlePreInit(event)"/>

Then in the event handling method retrieve the flashvar parameter like this:

private function handlePreInit(event:FlexEvent):void {

_contextURL = parameters['ContextURL'];
}

Then later on (after the APPLICATION_COMPLETE event) the context URL can be fed to the application
context instance again:

var applicationContext:XMLApplicationContext = new XMLApplicationContext();


applicationContext.addConfigLocation(_contextURL);
applicationContext.addEventListener(Event.COMPLETE, handleComplete);
applicationContext.load();

Composing XML-based configuration metadata


It can often be useful to split up container definitions into multiple XML files. One way to then load
an application context which is configured from all these XML fragments is to use the application
context constructor which takes multiple resource locations. Also, after construction of the container, more
locations can be added with the addConfigLocation() method.

Generally, the Spring Actionscript team prefers the above approach, since it keeps container configuration
files unaware of the fact that they are being combined with others. An alternate approach is to use one
or more occurrences of the element to load object definitions from another file (or files). Let's look at
a sample:

<objects>

<import file="services.xml"/>
<import file="resources/messageSource.xml"/>
<import file="/resources/themeSource.xml"/>

6
The Inversion of
Control (IoC) container

<object id="object1" class="..."/>


<object id="object2" class="..."/>

</objects>

The contents of the files being imported must be valid XML object definition files according to the Spring
Actionscript schema, including the top level element.

the object definition


<object/> elements can have a number of attributes that determine various properties and behaviors
of an object, its creation and wiring. Here's a list of all these properties with a link to their respective
documentation sections:

• abstract

• autowire

• autowire-candidate

• class

• dependency-check

• depends-on

• destroy-method

• factory-method

• factory-object

• id

• init-method

• lazy-init

• parent

• primary

• scope

• singleton (deprecated, use scope attribute instead)

• skip-metadata

• skip-postprocessors

• template

These element attributes will be mapped onto IObjectDefiniton instances after the XML has been parsed
by the application context. Object definitions can be defined in XML, MXML or annotations. Object
definitions can be augmented with constructor, property and method invocation definitions.

Embedding the XML metadata


In the case where an external XML file is not desirable or practical Spring Actionscript also allows you
to embed the XML metadata file in the application.

7
The Inversion of
Control (IoC) container

To do so embed the XML file like this:

[Bindable]
[Embed(source="application-context.xml",mimeType ="application/octet-stream")]
public var contextConfig:Class;

Note
For more information about embedding files visit this link:

After that the way to add the configuration location is slightly different:

var applicationContext:XMLApplicationContext = new XMLApplicationContext();


applicationContext.addEmbeddedConfig(contextConfig);
applicationContext.load();

Notice that we no longer need the Event.COMPLETE handler, since the configurations are embedded
they will be loaded and parsed synchronously, so after invoking addEmbeddedConfig() once or more and
calling load() the application context will be ready for use immediately.

Note
Of course, if you mix embedded and external metadata you will need to keep the
Event.COMPLETE handler and load() invocation for obvious reasons.

And that's all there is to it!

Declaring embedded import files


If your embedded configuration file also contains import declarations you will have to change the markup
slightly to let Spring Actionscript know where to find them. But first add your import configurations like
this:

[Bindable]
[Embed(source="services.xml",mimeType ="application/octet-stream")]
public var servicesContext:Class;

[Bindable]
[Embed(source="resources/messageSource.xml",mimeType ="application/octet-stream")]
public var messageSourceContext:Class;

[Bindable]
[Embed(source="/resources/themeSource.xml",mimeType ="application/octet-stream")]
public var themeSourceContext:Class;

Then inside your main configuration file, change the import markup like this:

<objects>

<import file="servicesContext" type="class"/>


<import file="messageSourceContext" type="class"/>
<import file="themeSourceContext" type="class"/>

<object id="object1" class="..."/>


<object id="object2" class="..."/>

8
The Inversion of
Control (IoC) container

</objects>

And again, that's all there is to it!

Note
Make sure to add the embedded Class instances as properties of your Application object, this
is the place where Spring Actionscript will look for these property names. If it fails to find the
specified names an Error will be thrown. Also, because this functionality is depended on the Flex
framework, it is only available when using the FlexXMLApplicationContext class, in other cases
the type='class' attribute will be ignored.

External property files


In some scenarios it might be useful to store certain properties of the config XML file externally so that
you can easily change them without having to wade through the entire configuration file or if you want to
re-use certain global values in different parts of the configuration, such as path data or URLs.

The application context allows you to specify external properties in separate Ant-like *.properties files.

You can then define property placeholders in your config files with the ${...} syntax. Here's an example.
Note that the path to the *.properties file is relative to the path of the configuration file.

<objects>

<property file="strings.properties" />

<object id="string1" class="String">


<constructor-arg value="${s1}"/>
</object>

<object id="string2" class="String">


<constructor-arg value="${s2}"/>
</object>

</objects>

And the strings.properties file contents would look like this:

s1=First string
s2=Second string

Its also possible to combine property values, that way a property value can be injected with other values,
for example:

s1=First String and {$s2}


s2=Second string

Note
To prevent the properties file from being cached by the web browser the XMLObjectFactory
by default will suffix the URL with a random number. To turn this off for a specified property
file use the prevent-cache attribute. For example: <property file="strings.properties" prevent-
cache="false"/>.

9
The Inversion of
Control (IoC) container

Note
By default the properties loader will throw an error if a properties file could not be
loaded, to ignore the error and resume loading set the required attribute to false: <property
file="strings.properties" required="false"/>

Define external properties explicitly


If you don't need an external file to store your properties in, yet you would like to define global properties
to be used throughout your configuration, its also possible to define the property values directly on the
<property/> tag:

<property name="s1" value="First string"/>


<property name="s2" value="Second string"/>

And, of course, here it is also possible to combine property values:

<property name="s1" value="First string and {$s2}"/>


<property name="s2" value="Second string"/>

Note
The file attribute will take precedence over the name and value attributes, so when both are
declared the name and value attributes will be ignored.

Flashvars converted to properties


The FlexXMLApplicationContext will automatically add any flashvars that were passed to the application
to its properties collection. The name of the flashvar can then be used in the same way as an application
setting property. For example: ${application.myFlashVar}.

The class responsible for this is the FlexPropertyPlaceholderConfigurer. For more about the application
setting read this section.

The objects
A Spring Actionscript IoC container manages one or more objects. These objects are created using the
configuration metadata that has been supplied to the container (typically in the form of XML definitions).

Within the container itself, these object definitions are represented as ObjectDefinition objects, which
contain (among other information) the following metadata:

Table 2.1. The object definition


Feature Explained in...
class Instantiating objects
name Naming objects
constructor arguments Injecting dependencies
properties Injecting dependencies
autowiring mode Autowiring collaborators
lazy-initialization mode Lazily-instantiated objects
initialization method Initialization callbacks

10
The Inversion of
Control (IoC) container

Naming objects
Every object has one or more ids (also called identifiers, or names; these terms refer to the same thing).
These ids must be unique within the container the object is hosted in.

When using XML-based configuration metadata, you use the 'id' attribute to specify the object identifier(s).
The 'id' attribute allows you to specify exactly one id, and as it is a real XML element ID attribute, the
XML parser is able to do some extra validation when other elements reference the id; as such, it is the
preferred way to specify an object id. However, the XML specification does limit the characters which
are legal in XML IDs.

Instantiating objects
An object definition essentially is a recipe for creating one or more objects. The container looks at the
recipe for a named object when asked, and uses the configuration metadata encapsulated by that object
definition to create (or acquire) an actual object.

If you are using XML-based configuration metadata, you can specify the type (or class) of the object
that is to be instantiated using the 'class' attribute of the element. This 'class' attribute (which internally
eventually boils down to being a Class property on a ObjectDefinition instance) is normally mandatory
(see Section "" for the exception) and is used for one of two purposes. The class property specifies the
class of the object to be constructed in the common case where the container itself directly creates the
object by calling its constructor (somewhat equivalent to Actionscript code using the 'new' operator). In
the less common case where the container invokes a static, factory method on a class to create the object,
the class property specifies the actual class containing the static factory method that is to be invoked to
create the object (the type of the object returned from the invocation of the static factory method may be
the same class or another class entirely, it doesn't matter).

Instantiation through a parent factory


Object factories can form a hierarchy through the parent property of an IObjectFactory implementation
such as the AbstractObjectFactory. By assigning another IObjectFactory instance to this parent property
the getObject() method will first see if the current object factory can create the requested object instance,
if no appropriate ObjectDefinition can be found it will request it from its parent factory.

A simple example of an application context hierarchy

Imagine a scenario with two application contexts. One is created by the main application and the other is
created inside a module that is loaded at a later time.

We will refer to the first as application context and the latter as module context.

Now imagine the configuration of the application context to look like this:

<objects>

<object class="com.myclasses.MyObject" id="myObject" scope="singleton"/>

<object class="com.myclasses.MyOtherObject" id="myOtherObject" scope="prototype"/>

</objects>

And the module context looking like this:

<objects>

11
The Inversion of
Control (IoC) container

<object class="com.myclasses.moduleimplementations.MyOtherObject" id="myOtherObjec

</objects>

When the module context is created, we will set the application context as its parent:

var moduleContext:XMLApplicationContext = new XMLApplicationContext("module-context


moduleContext.parent = applicationContext;

The result of this is that, when an object with id myOtherObject is requested from the application
context, you will receive an instance of type com.myclasses.MyOtherObject. However, when you
request the same object id from the module context, you will receive an instance of type
com.myclasses.moduleimplementations.MyOtherObject.

Next, we change both configurations slightly, add some dependencies and show how to override those
dependencies in a the module configuration.

Here's how the application context's configuration looks:

<objects>

<object class="com.myclasses.MyObject" id="myObject" scope="singleton"/>

<object class="com.myclasses.MyOtherObject" id="myOtherObject" scope="prototype">


<property name="dependency" ref="myDependency"/>
</object>

<object class="com.dependencies.MyDependency" id="myDependency"/>

</objects>

Now requesting an object with id myOtherObject from the application context will yield you an instance
of type com.myclasses.MyOtherObject with a dependency property value set to an instance of type
com.dependencies.MyDependency.

After that we change the module context configuration to look like this:

<objects>

<object class="com.moduledependencies.MyDependency" id="myDependency"/>

</objects>

When we subsequently request an object with id myOtherObject from the module context the result will
be an instance of type com.myclasses.MyOtherObject with a dependency property value set to an instance
of type com.moduledependencies.MyDependency.

Note
Overriding references like this will only work on objects that are scoped as prototype, this is
because its very probable that the object has already been cached by the parent context when
requested, and injecting singletons created by the parent with dependencies created by the module
context will suddenly put a dependency from the application context on the module context,
which is undesirable.

12
The Inversion of
Control (IoC) container

It is also possible to replace properties with values that are available in the parent context, but this is not
enabled by default. To enable this, the "useParentObjectFactoryPostProcessors" on the child context must
be set to "true". (note: as the name of this property suggests, all ObjectFactoryPostProcessors defined in
parent contexts will be applied to the child context. The PropertyPlaceholderConfigurer that is responsible
for replacing property placeholders is one of them.)

So if the application context holds an external property by the name of prop1 it is possible declare an
object definition in the module context like this:

<objects>

<object class="com.moduleclasses.MyObjectWithAProperty" id="myObjectWithAProperty"


<property name="myProperty" value="{$prop1}"/>
</object>

</objects>

Unloading modules
Before unloading a module, be sure to invoke the dispose() method on any application context instance
that is associated with it. This will release all the resources that the context is holding and will make it,
and the module, eligible for garbage collection after unloading.

Disposing (releasing) container managed objects

Like the application context, also objects that are managed by the context may need to have a disposal
method in which they are able to release any resources they are holding. There are two ways of letting the
context know which methods need to be invoked on an object once the context itself is being disposed:

• The IDisposable interface

• The destroy-method attribute on an object definition

The IDisposable interface

The IDisposable interface is quite small, its signature look like this and is self-explanatory:

public interface IDisposable {


function get isDisposed():Boolean;
function dispose():void;
}

If an object is encountered in the context that implements this interface its dispose() method will be invoked
once the context itself is being disposed.

The destroy-method attribute

To avoid any dependencies on framework classes and interfaces the destroy (for the IDisposable interface
this would be its dispose() method) method for an object can also be defined in its associated object
definition like this:

<object class="..." destroy-method="release"/>

Destroying stage components

The DefaultAutowiringStageProcessor will also be invoked after a component is removed from the stage.
It will check the application context for the existence of an object definition for the specified component,
and when found, see if a destroy method has been defined. If this is the case, this method will be invoked.

13
The Inversion of
Control (IoC) container

If an IObjectDefinition wasn't found for the specified component it will check if the component perhaps
implements the IDisposable interface. If so, its dispose() method will be invoked. See the section 'The
IStageDestroyer interface' to learn more about the underlying architecture for this functionality and how
to extend it.

Instantiation using a constructor


When creating an object using the constructor approach, all normal classes are usable by and compatible
with Spring Actionscript. That is, the class being created does not need to implement any specific interfaces
or be coded in a specific fashion. Just specifying the object class should be enough. However, depending on
what type of IoC you are going to use for that specific object, you may need a default (empty) constructor.

When using XML-based configuration metadata you can specify your object class like so:

<object id="exampleObject" class="examples.ExampleObject"/>

<object name="anotherExample" class="examples.ExampleObjectTwo"/>

The Actionscript equivalent of which would be:

var exampleObject:ExampleObject;

var anotherExample:ExampleObjectTwo;

And instantiating one of them by the IoC container would look like this:

var exampleObject:ExampleObject = applicationContext.getObject("exampleObject") as

Which in regular Actionscript would look like this:

var exampleObject:ExampleObject = new ExampleObject();

The mechanism for supplying arguments to the constructor (if required), or setting properties of the object
instance after it has been constructed, is described shortly.

Object factory events

The object factory dispatches two events after creating or retrieving an object instance from it. Namely
ObjectFactoryEvent.OBJECT_CREATED and ObjectFactoryEvent.OBJECT_RETRIEVED. The first is
dispatched right after an object instance has been instantiated and wored by the object factory, the second
right before its returned by the getObject() method. These events are both dispatched by the object factory
and through the EventBus. To learn more about the EventBus, check out the chapter 'The EventBus'.

Instantiation using a static factory method


When defining an object which is to be created using a static factory method, along with the class attribute
which specifies the class containing the static factory method, another attribute named factory-method is
needed to specify the name of the factory method itself. Spring Actionscript expects to be able to call this
method and get back a live object, which from that point on is treated as if it had been created normally
via a constructor. One use for such an object definition is to call static factories in legacy code, but it can
also be used to retrieve objects that have been instantiated in MXML and are later pulled into the IoC
container to be configured.

The following example shows an object definition which specifies that the object is to be created by calling
a factory-method. Note that the definition does not specify the type (class) of the returned object, only the
class containing the factory method. In this example, the getInstance() method must be a static method.

<object id="exampleObject"

14
The Inversion of
Control (IoC) container

class="examples.ExampleObjectLocator"
factory-method="getInstance"/>

Of which the Actionscript equivalent would be:

var exampleObject:ExampleObject = ExampleObjectLocator.getInstance();

Instantiation using a factory method on a different instance


The previous section explained how to use a static factory method on a class, here's how to use a factory
method on a different instance.

<object id="exampleFactory"
class="examples.ExampleObjectFactory"/>

<object id="exampleObject" class="examples.Example"


factory-object="exampleFactory"
factory-method="getInstance"/>

And for this the Actionscript equivalent would be:

var exampleFactory:ExampleObjectFactory = new ExampleObjectFactory();

var exampleObject:ExampleObject = exampleFactory.getInstance();

Composing MXML-based configuration metadata


Besides an external or embedded configuration defined in an XML file, Spring Actionscript also offers
you the ability to configure your objects through MXML markup. The markup is very similar to the regular
XML version, but with some slight differences, we will list them below.

MXML configuration is done by creating one or more MXML files containing objects or object definitions
and loading them via the MXMLApplicationContext class. The difference here with XML configurations
is that you can either define objects explicitly in MXML (e.g. <mx:RemoteObject/>) or implicitly via the
<Object/> element. The <Object/> element is the same as using the <object/> in XML configuration.

Declaring the Spring Actionscript namespace


In order to create object definitions in MXML, we let Flex know where to find the components. We do
that by declaring its namespace as follows (in MyConfig.mxml for instance):

<?xml version="1.0"?>
<Objects
xmlns="http://www.springactionscript.org/mxml/config"
xmlns:mx="http://www.adobe.com/2006/mxml">

Adding object definitions


Now to add object definitions you add these MXML components as children to the MXML config.

<Object id="remoteObject" clazz={mx.rpc.remoting.mxml.RemoteObject}>


<Property name="destination" value="ColdFusion"/>
<Property name="concurrency" value="multiple"/>
<Property name="makeObjectsBindable" value="false"/>
<Property name="showBusyCursor" value="true"/>
<Property name="source" value="com.serverside.remote.remoteGateway"/>
</Object>

15
The Inversion of
Control (IoC) container

Notice you can define the class of the object with the clazz property which is of type Class. This way
you will have compile-time checking of the classes you include in your application context. This is an
advantage over regular XML based configuration where you need to make sure that all classes are included
by hand.

Instantiating the MXMLApplicationContext


To use this configuration, all we need to do is create an instance of the MXMLApplicationContext class,
add the configurations to it and invoke its load method. This will (asynchronously) load and initialize the
application context.

private var appContext:MXMLApplicationContext;

public function applicationCompleteHandler(event:FlexEvent):void {


appContext = new MXMLApplicationContext();
appContext.addConfig(MyConfig);
appContext.addEventListener(Event.COMPLETE, appContext_completeHandler);
appContext.load();
}

Notice that we pass in the class of the configuration file and not an instance.

Using property placeholders


We can also use property placeholders inside objects and object definitions defined in MXML. This has
the advantage that we can load properties defined externally into the MXML configuration so we do not
need to recompile the application when these properties need to be changed. A typical example of this is
the configuration of service endpoints.

Below are some examples of property placeholders in MXML configuration.

<Objects
xmlns="http://www.springactionscript.org/mxml/config"
xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:context="org.springextensions.actionscript.ioc.factory.config.*">

<mx:Script>
<![CDATA[
import mx.rpc.remoting.mxml.RemoteObject;
]]>
</mx:Script>

<context:PropertyPlaceholderConfigurer locations="{['properties.properties.txt', '

<Object id="string1" clazz="{String}">


<ConstructorArg>$(property1)</ConstructorArg>
</Object>

<mx:Array id="propertiesArray">
<mx:String>$(property1)</mx:String>
<mx:String>$(property2)</mx:String>
<mx:String>$(property3)</mx:String>
</mx:Array>

<mx:RemoteObject endpoint="http://$(host):$(port)/$(context-root)/messagebroker/am

16
The Inversion of
Control (IoC) container

<mx:RemoteObject id="remoteObject1" endpoint="http://$(host):$(port)/$(context-roo

<mx:RemoteObject id="remoteObject2">
<mx:endpoint>http://$(host):$(port)/$(context-root)/messagebroker/amf</mx:endpoin
</mx:RemoteObject>

<Object id="remoteObjectDefinitionWithPlaceHolders" clazz="{RemoteObject}">


<Property name="endpoint" value="http://$(host):$(port)/$(context-root)/messagebr
</Object>

</Objects>

Using the container


An XMLApplicationContext (or FlexXMLApplicationContext) is essentially nothing more than the
interface for an advanced factory capable of maintaining a registry of different objects and their
dependencies. The XMLApplicationContext, which is also an implementation of the IObjectFactory
interface, enables you to read object definitions and access them using the getObject() method. When
using just the XMLApplicationContext you would create one and read in some object definitions in the
XML format as follows:

var applicationContext:XMLApplicationContext = new XMLApplicationContext();


applicationContext.addConfigLocation("application-context.xml");
applicationContext.addEventListener(Event.COMPLETE, handleComplete);
applicationContext.load();

And in the handleComplete method (or any other code which runs after this event has fired) you access
your object like this:

public function handleComplete(event:FlexEvent):void {

var exampleObject:ExampleObject = applicationContext.getObject("exampleObject")


}

Basically that is all there is to it. Using getObject(String) you can retrieve instances of your object; the
client-side view of the XMLApplicationContext is simple. The XMLApplicationContext object has just
a few other methods, but ideally your application code should never use them... Ideally, your application
code should have no calls to the getObject(String) method at all, and thus no dependency on Spring
Actionscript APIs at all.

Dependencies
Your typical enterprise application is not made up of a single object. Even the simplest of applications
will no doubt have at least a handful of objects that work together to present what the end-user sees as a
coherent application. This next section explains how you go from defining a number of object definitions
that stand-alone, each to themselves, to a fully realized application where objects work (or collaborate)
together to achieve some goal (usually an application that does what the end-user wants).

Injecting dependencies
The basic principle behind Dependency Injection (DI) is that objects define their dependencies (that is to
say the other objects they work with) only through constructor arguments, arguments to a factory method,
or properties which are set on the object instance after it has been constructed or returned from a factory
method. Then, it is the job of the container to actually inject those dependencies when it creates the object.

17
The Inversion of
Control (IoC) container

This is fundamentally the inverse, hence the name Inversion of Control (IoC), of the object itself being
in control of instantiating or locating its dependencies on its own using direct construction of classes, or
something like the Service Locator pattern.

It becomes evident upon usage that code gets much cleaner when the DI principle is applied, and reaching a
higher grade of decoupling is much easier when objects do not look up their dependencies, but are provided
with them (and additionally do not even know where the dependencies are located and of what concrete
class they are). DI exists in two major variants, namely and .

Constructor Injection
Constructor-based DI is effected by invoking a constructor with a number of arguments, each representing
a dependency. Find below an example of a class that could only be dependency injected using constructor
injection. Notice that there is nothing special about this class.

public class SimpleMovieLister {

// the SimpleMovieLister has a dependency on a MovieFinder


private _movieFinder:MovieFinder;

// a constructor so that the Spring Actionscript container can 'inject' a Movie


public SimpleMovieLister(movieFinder:MovieFinder) {
_movieFinder = movieFinder;
}

// business logic that actually 'uses' the injected MovieFinder is omitted...


}

Setter Injection
Setter-based DI is realized by calling setter methods or plainly setting properties on your objects after
invoking a no-argument constructor or no-argument static factory method to instantiate your object. Find
below an example of a class that can only be dependency injected using pure setter injection. Note that
there is nothing special about this class... it is plain old Actionscript.

public class SimpleMovieLister {

// the SimpleMovieLister has a dependency on the MovieFinder


private _movieFinder:MovieFinder;

// a setter method so that the Spring container can 'inject' a MovieFinder


public function set movieFinder(value:MovieFinder):void {
if (value !== this._movieFinder){
this._movieFinder = movieFinder;
}
}

// business logic that actually 'uses' the injected MovieFinder is omitted...


}

The XMLObjectFactory supports both of these variants for injecting dependencies into objects it manages.
(It in fact also supports injecting setter-based dependencies after some dependencies have already been
supplied via the constructor approach.) The configuration for the dependencies comes in the form of an
ObjectDefinition, which is used together with IPropertyEditor implementations to know how to convert
properties from one format to another. However, most users of Spring Actionscript will not be dealing

18
The Inversion of
Control (IoC) container

with these classes directly (that is programmatically), but rather with an XML definition file which will
be converted internally into instances of these classes, and used to load an entire Spring IoC container
instance.

Object dependency resolution generally happens as follows:

• The XMLObjectFactory is created and initialized with a configuration which describes all the objects.
(Most Spring Actionscript users use an ApplicationContext implementation that supports XML format
configuration files.)

• Each object has dependencies expressed in the form of properties, constructor arguments, or arguments
to the static-factory method when that is used instead of a normal constructor. These dependencies will
be provided to the object, when the object is actually created.

• Each property or constructor argument is either an actual definition of the value to set, or a reference
to another object in the container.

• Each property or constructor argument which is a value must be able to be converted from whatever
format it was specified in, to the actual type of that property or constructor argument. By default Spring
can convert a value supplied in string format to all built-in types, such as int, uint, String, Boolean, etc.

The Spring Actionscript container validates the configuration of each object as the container is created,
including the validation that properties which are object references are actually referring to valid
objects. However, the object properties themselves are not set until the object is actually created. For
those objects that are singleton-scoped and set to be pre-instantiated (such as singleton objects in an
ApplicationContext), creation happens at the time that the container is created, but otherwise this is only
when the object is requested. When an object actually has to be created, this will potentially cause a graph
of other objects to be created, as its dependencies and its dependencies' dependencies (and so on) are
created and assigned.

You can generally trust Spring Actionscript to do the right thing. It will detect misconfiguration issues, such
as references to non-existent objects and circular dependencies, at container load-time. It will actually set
properties and resolve dependencies as late as possible, which is when the object is actually created. This
means that a Spring Actionscript container which has loaded correctly can later generate an exception when
you request an object if there is a problem creating that object or one of its dependencies. This could happen
if the object throws an exception as a result of a missing or invalid property, for example. This potentially
delayed visibility of some configuration issues is why ApplicationContext implementations by default pre-
instantiate singleton objects. At the cost of some upfront time and memory to create these objects before
they are actually needed, you find out about configuration issues when the ApplicationContext is created,
not later. If you wish, you can still override this default behavior and set any of these singleton objects to
lazy-initialize (that is not be pre-instantiated).

If no circular dependencies are involved (see sidebar for a discussion of circular dependencies), when one
or more collaborating objects are being injected into a dependent object, each collaborating object is totally
configured prior to being passed (via one of the DI flavors) to the dependent object. This means that if
object A has a dependency on object B, the Spring Actionscript IoC container will totally configure object
B prior to invoking the setter method on object A; you can read 'totally configure' to mean that the object
will be instantiated (if not a pre-instantiated singleton), all of its dependencies will be set, and the relevant
lifecycle methods (such as a configured init method) will all be invoked.

Method invocations
To invoke one or more methods after the object has been constructed by the container add <method-
invocation/> elements to the <object/> element.

<object id="exampleObject" class="examples.ExampleObject">

19
The Inversion of
Control (IoC) container

<method-invocation name="someMethod"/>
</object>

If the method in question needs any kind of arguments, add them like this:

<object id="exampleObject" class="examples.ExampleObject">


<method-invocation name="someMethod">
<arg value="${externalPropertyName}"/> //External property value
<arg ref="anotherExampleObject"/> //Another object instance managed by the
<arg> //Another object instance defined inline
<object class="..."/>
</arg>
</method-invocation>
</object>

<object id="anotherExampleObject" class="examples.AnotherObject"/>

Some examples
First, an example of using XML-based configuration metadata for setter-based DI. Find below a small part
of a Spring Actionscript XML configuration file specifying some object definitions.

<object id="exampleObject" class="examples.ExampleObject">

<!-- setter injection using the nested <ref/> element -->


<property name="objectOne"><ref>anotherExampleObject</ref></property>

<!-- setter injection using the neater 'ref' attribute -->


<property name="objectTwo" ref="yetAnotherObject"/>

<property name="integerProperty" value="1"/>

<property name="booleanProperty" value="true"/>


</object>

<object id="anotherExampleObject" class="examples.AnotherObject"/>

<object id="yetAnotherObject" class="examples.YetAnotherObject"/>

public class ExampleObject {

private var _objectOne:AnotherObject;


private var _objectTwo:YetAnotherObject;
private var _i:int;
private var _bool:Boolean;

public function set objectOne(value:AnotherObject):void {


if (value !== _objectOne){
_objectOne = value;
}
}

public function set objectTwo(value:YetAnotherObject):void {


if (value !== _objectTwo)
_objectTwo = value;

20
The Inversion of
Control (IoC) container

}
}

public function set integerProperty(value:int):void {


if (value != _i){
_i = value;
}
}

public function set booleanProperty(value:Boolean):void {


if (value != _bool){
_bool = value;
}
}
}

As you can see, setters have been declared to match against the properties specified in the XML file. Find
below an example of using constructor-based DI.

<object id="exampleObject" class="examples.ExampleObject">

<!-- constructor injection using the nested <ref/> element -->


<constructor-arg>
<ref>anotherExampleObject</ref>
</constructor-arg>

<!-- constructor injection using the neater 'ref' attribute -->


<constructor-arg ref="yetAnotherObject"/>

<constructor-arg value="1"/>

<constructor-arg value="true"/>
</object>

<object id="anotherExampleObject" class="examples.AnotherObject"/>


<object id="yetAnotherObject" class="examples.YetAnotherObject"/>

public class ExampleObject {

private var _objectOne:AnotherObject;


private var _objectTwo:YetAnotherObject;
private var _i:int;
private var _bool:Boolean;

public ExampleObject(anotherObject:AnotherObject, yetAnotherObject:YetAnotherOb


_objectOne = anotherobject;
_objectTwo = yetAnotherobject;
_i = i;
_bool = b;
}
}

Notice, the constructor arguments specified in the object definition will be used to pass in as arguments to
the constructor of the ExampleObject. Now consider a variant of this where instead of using a constructor,
Spring Actionscript is told to call a static factory method to return an instance of the object:

21
The Inversion of
Control (IoC) container

<object id="exampleObject" class="examples.ExampleObjectFactory" factory-method="cr


<constructor-arg ref="anotherExampleObject"/>
<constructor-arg ref="yetAnotherObject"/>
<constructor-arg value="1"/>
</object>

<object id="anotherExampleObject" class="examples.AnotherObject"/>


<object id="yetAnotherObject" class="examples.YetAnotherObject"/>

public final class ExampleObjectFactory {

// a static factory method; the arguments to this method can be


// considered the dependencies of the object that is returned,
// regardless of how those arguments are actually used.
public static createInstance(anotherObject:AnotherObject, yetAnotherObject:YetA

var eb:ExampleObject = new ExampleObject(...);


// some other operations...
return eb;
}
}

Note that arguments to the static factory method are supplied via elements, exactly the same as if a
constructor had actually been used. Also, it is important to realize that the type of the class being returned
by the factory method does not have to be of the same type as the class which contains the static factory
method.

Dependencies and configuration in detail


As mentioned in the previous section, object properties and constructor arguments can be defined as either
references to other managed objects (collaborators), or values defined inline. Spring Actionscript's XML-
based configuration metadata supports a number of sub-element types within its and elements for just
this purpose.

Straight values (primitives, Strings, etc.)


The element specifies a property or constructor argument as a human-readable string representation. As
mentioned previously, IPropertyEditor implementations are used to convert these string values from a
String to the actual type of the property or argument.

<object id="amfChannel" class="mx.messaging.channels.AMFChannel">


<constructor-arg>
<value>my-amf</value>
</constructor-arg>
<constructor-arg>
<value>http://{server.name}:{server.port}/flex2gateway/</value>
</constructor-arg>
<property name="pollingEnabled">
<value>false</value>
</property>
</object>

The and elements also support the use of the 'value' attribute, which can lead to much more succinct
configuration. When using the 'value' attribute, the above object definition reads like so:

22
The Inversion of
Control (IoC) container

<object id="amfChannel" class="mx.messaging.channels.AMFChannel">


<constructor-arg value="my-amf"/>
<constructor-arg value="http://{server.name}:{server.port}/flex2gateway/"/>
<property name="pollingEnabled" value="false"/>
</object>

References to other objects (collaborators)


The ref element is the final element allowed inside a or definition element. It is used to set the value
of the specified property to be a reference to another object managed by the container (a collaborator).
As mentioned in a previous section, the referred-to object is considered to be a dependency of the object
who's property is being set, and will be initialized on demand as needed (if it is a singleton object it may
have already been initialized by the container) before the property is set. All references are ultimately just
a reference to another object.

Specifying the target object by using the tag is the most general form.

<ref>myTargetObject</ref>

Inner objects
An element inside the or elements is used to define a so-called inner object. An inner object definition
does not need to have any id defined, and it is best not to even specify any id value because the id value
simply will be ignored by the container.

<object id="outer" class="...">


<!-- instead of using a reference to a target object, simply define the target ob
<property name="target">
<object class="com.example.Person"> <!-- this is the inner object -->
<property name="name" value="Fiona Apple"/>
<property name="age" value="25"/>
</object>
</property>
</object>

Note that in the specific case of inner objects, the 'scope' flag and any 'id' attribute are effectively ignored.
Inner objects are always anonymous and they are always scoped as prototypes. Please also note that it is
not possible to inject inner objects into collaborating objects other than the enclosing object.

Collections
The , , and <vector/> elements allow properties and arguments of the Actionscript collection type
Array, ArrayCollection, Dictionary and Vector, respectively, to be defined and set.

Be aware that the array-collection type can only be used in a Flex based application (using the
FlexXMLApplicationContext) object since it is part of the framework.

Also be careful only to use the Vector type in applications that are made for Flash player version 10 or
higher.

<object id="moreComplexObject" class="example.ComplexObject">


<property name="adminEmails">
<dictionary>
<entry key="administrator" value="administrator@example.org"/>

23
The Inversion of
Control (IoC) container

<entry key="support" value="support@example.org"/>


<!-- or a more verbose way of defining an entry -->
<entry>
<key>development</key>
<value>development@example.org</value>
</entry>
</dictionary>
</property>

<property name="someList">
<array>
<value>a list element followed by a reference</value>
<value><ref object="myOtherObject" /></value>
</array>
</property>

<!-- Only use this in a Flex based application -->


<property name="someOtherList">
<array-collection>
<value>a list element followed by a reference</value>
<value><ref object="myOtherObject" /></value>
</array-collection>
</property>

<!-- Only use this in an application made for Flash player 10 and higher -->
<property name="vectorProperty">
<vector type="String">
<value>string1</value>
<value>string2</value>
<value>string3</value>
<value>string4</value>
</vector>
</property>

</object>

Note
The nested element style used this initial example tends to become quite verbose. Fortunately,
there are attribute shortcuts for most elements, which you can read about in Shortcuts and other
convenience options for XML-based configuration metadata.

Injecting the application context using the 'this' reference


Injecting the application context can be achieved by using the id 'this' as reference:

<method-invocation name="someMethod">
<arg ref="this"/>
</method-invocation>

This works for property chains on the application context as well, for example:

<method-invocation name="someMethod">
<arg ref="this.applicationDomain"/>

24
The Inversion of
Control (IoC) container

</method-invocation>

Shortcuts and other convenience options for XML-based


configuration metadata
The configuration metadata shown so far is a tad verbose. That is why there are several options available
for you to limit the amount of XML you have to write to configure your components. The first is a shortcut
to define values and references to other objects as part of a definition. The second is slightly different
format of specifying properties altogether.

XML-based configuration metadata shortcuts


The , , and elements all support a 'value' attribute which may be used instead of embedding a full element.
Therefore, the following:

<property name="myProperty">
<value>hello</value>
</property>

<constructor-arg>
<value>hello</value>
</constructor-arg>

<entry key="myKey">
<value>hello</value>
</entry>

are equivalent to:

<property name="myProperty" value="hello"/>

<constructor-arg value="hello"/>

<entry key="myKey" value="hello"/>

Using depends-on
For most situations, the fact that an object is a dependency of another is expressed by the fact that one
object is set as a property of another. This is typically accomplished with the element in XML-based
configuration metadata. For the relatively infrequent situations where dependencies between objects are
less direct, the 'depends-on' attribute may be used to explicitly force one or more objects to be initialized
before the object using this element is initialized. Find below an example of using the 'depends-on' attribute
to express a dependency on a single object.

<object id="objectOne" class="ExampleObject" depends-on="manager"/>

<object id="manager" class="ManagerObject" />

If you need to express a dependency on multiple objects, you can supply a list of object names as the value
of the 'depends-on' attribute, with commas, whitespace and semicolons all valid delimiters, like so:

<object id="objectOne" class="ExampleObject" depends-on="manager,accountDao">


<property name="manager" ref="manager" />
</object>

25
The Inversion of
Control (IoC) container

<object id="manager" class="ManagerObject" />


<object id="accountDao" class="x.y.as.AccountDao" />

Ensuring dependency injection with dependency check


Spring Actionscript has 4 different validation modes to check if properties have been on an object. The
different dependency check modes are 'none', 'simple', 'object', and 'all'. The default mode is 'none', so
there isn't any dependency check validation unless explicitly configured. All values being checked must
have been set in the configuration file or by autowiring. If a class has any defaults or fields that don't need
to be set, the dependency check modes won't be of any use.

Table 2.2. Autowiring modes


Mode Explanation
none No dependency checking. This is the default.
simple Dependency check for primitives and collections.
object Dependency check for objects (collaborators).
all Dependency check for primitives, collections, and
objects (collaborators).

The 'simple' mode checks that all primitive and collection values have been set. The 'object' mode checks
that all collaborators (objects) have been set. The 'all' mode checks for everything that the 'simple' and
'object' modes do.

Lazily-instantiated objects
The default behavior for IApplicationContext implementations is to eagerly pre-instantiate all singleton
objects at startup. Pre-instantiation means that an IApplicationContext will eagerly create and configure all
of its singleton objects as part of its initialization process. Generally this is a good thing, because it means
that any errors in the configuration or in the surrounding environment will be discovered immediately (as
opposed to possibly hours down the line).

However, there are times when this behavior is not what is desired. If you do not want a singleton object
to be pre-instantiated when using an IApplicationContext, you can selectively control this by marking an
object definition as lazily-initialized. A lazily-initialized object indicates to the IoC container whether or
not an object instance should be created at startup or when it is first requested.

When configuring objects via XML, this lazy loading is controlled by the 'lazy-init' attribute on the
element; for example:

<object id="lazy" class="com.foo.ExpensiveToCreateObject" lazy-init="true"/>

<object name="not.lazy" class="com.foo.AnotherObject"/>

When the above configuration is consumed by an IApplicationContext, the object named 'lazy' will not
be eagerly pre-instantiated when the IApplicationContext is starting up, whereas the 'not.lazy' object will
be eagerly pre-instantiated.

One thing to understand about lazy-initialization is that even though an object definition may be marked
up as being lazy-initialized, if the lazy-initialized object is the dependency of a singleton object that is
not lazy-initialized, when the IApplicationContext is eagerly pre-instantiating the singleton, it will have
to satisfy all of the singletons dependencies, one of which will be the lazy-initialized object! So don't
be confused if the IoC container creates one of the objects that you have explicitly configured as lazy-

26
The Inversion of
Control (IoC) container

initialized at startup; all that means is that the lazy-initialized object is being injected into a non-lazy-
initialized singleton object elsewhere.

A graphical overview of the getObject() flow


See below for a graphical overview of the program flow that happens after you call the getObject() method
on an application context instance.

A graphical overview of the wiring flow of an object


See below for a graphical overview of the program flow that happens when an object is being wired by
the application context.

Autowiring collaborators
The Spring Actionscript container is able to autowire relationships between collaborating objects. This
means that it is possible to automatically let Spring Actionscript resolve collaborators (other objects)
for your object by inspecting the contents of the ObjectDefinition. The autowiring functionality has five
modes. Autowiring is specified per object and can thus be enabled for some objects, while other objects will
not be autowired. Using autowiring, it is possible to reduce or eliminate the need to specify properties or
constructor arguments, thus saving a significant amount of typing. When using XML-based configuration
metadata, the autowire mode for a object definition is specified by using the autowire attribute of the
element. The following values are allowed:

Table 2.3. Autowiring modes


Mode Explanation
no No autowiring at all. Object references must be
defined via a ref element. This is the default, and
changing this is discouraged for larger deployments,
since explicitly specifying collaborators gives
greater control and clarity. To some extent, it is
a form of documentation about the structure of a
system.
byName Autowiring by property name. This option will
inspect the container and look for an object named
exactly the same as the property which needs to
be autowired. For example, if you have an object
definition which is set to autowire by name, and it
contains a master property, Spring Actionscript will
look for an object definition named master, and
use it to set the property.
byType Allows a property to be autowired if there is exactly
one object of the property type in the container. If
there is more than one, a fatal exception is thrown,
and this indicates that you may not use byType
autowiring for that object. If there are no matching
objects, nothing happens; the property is not set.

27
The Inversion of
Control (IoC) container

Mode Explanation
constructor This is analogous to byType, but applies to
constructor arguments. If there isn't exactly one
object of the constructor argument type in the
container, a fatal error is raised.
autodetect Chooses constructor or byType through
introspection of the object class. If a default
(parameterless) constructor is found, the byType
mode will be applied.

Note that explicit dependencies in and settings always override autowiring. Please also note that it is not
currently possible to autowire so-called simple properties such as primitives, Strings, and Classes
(and arrays of such simple properties). (This is by-design and should be considered a feature.) When using
either the byType or constructor autowiring mode, it is possible to wire arrays. In such cases all autowire
candidates within the container that match the expected type will be provided to satisfy the dependency.

It is important to understand the various advantages and disadvantages of autowiring. Some advantages
of autowiring include:

• Autowiring can significantly reduce the volume of configuration required. However, mechanisms such
as the use of a object template (discussed elsewhere in this chapter) are also valuable in this regard.

• Autowiring can cause configuration to keep itself up to date as your objects evolve. For example, if you
need to add an additional dependency to a class, that dependency can be satisfied automatically without
the need to modify configuration. Thus there may be a strong case for autowiring during development,
without ruling out the option of switching to explicit wiring when the code base becomes more stable.

Some disadvantages of autowiring:

• Autowiring is more magical than explicit wiring. Although, as noted in the above table, Spring
Actionscript is careful to avoid guessing in case of ambiguity which might have unexpected results, the
relationships between your Spring Actionscript-managed objects are no longer documented explicitly.

• Wiring information may not be available to tools that may generate documentation from a Spring
Actionscript container.

Another issue to consider when autowiring by type is that multiple object definitions within the container
may match the type specified by the setter method or constructor argument to be autowired. For arrays,
collections, or maps, this is not necessarily a problem. However for dependencies that expect a single
value, this ambiguity will not be arbitrarily resolved. Instead, if no unique object definition is available,
an Exception will be thrown. You do have several options when confronted with this scenario. First,
you may abandon autowiring in favor of explicit wiring. Second, you may designate that certain object
definitions are never to be considered as candidates by setting their 'autowire-candidate' attributes to
'false' as described in the next section. Third, you may designate a single object definition as the primary
candidate by setting the 'primary' attribute of its element to 'true'.

When deciding whether to use autowiring, there is no wrong or right answer in all cases. A degree of
consistency across a project is best though; for example, if autowiring is not used in general, it might be
confusing to developers to use it just to wire one or two object definitions.

Note
If a property is of type IApplicationContext or ApplicationDomain the application context
instance or its ApplicationDomain will be injected when autowiring byType.

28
The Inversion of
Control (IoC) container

A graphical overview of the autowiring flow of an object


As you can see its possible to combine the different types of wiring, the types take this override precedence:

1. Wire properties explicitly defined in the IObjectDefinition from the configuration

2. Wire properties by name or type as defined by the class annotations (metadata)

3. Wire properties by name or type as defined in the IObjectDefinition

Autowiring objects using annotations


A different way of letting the Spring Actionscript container know how to configure an object is by
adding specific metadata annotations to the component's sources. Obviously this is only possible when
the developer actually has access to the source code. Thus, this solution does not apply to the situation in
which you'd like to autowire existing objects, such as the ones that are already part of the Flex framework.

The simplest way to inject a property by type is by decorating its source like this:

public class ExampleComponent extends UIComponent {

[Autowired]
public var modelInstance:IModelLocator;

public function ExampleComponent() {


super();
}

Once this component is created (or added to the stage), the Spring Actionscript container will search
in its container an object of type IModelLocator and assign it to the modelInstance property of the
ExampleComponent.

Wiring by name is also possible, all that is needed is a little extra metadata:

public class ExampleComponent extends UIComponent {

[Autowired(mode='byName')]
public var modelInstance:IModelLocator;

public function ExampleComponent() {


super();
}

Now the Spring Actionscript container will look for an object in its configuration with the id
'modelInstance' and assign this to the modelInstance property of the ExampleComponent.

There's another way of injecting by name, suited for the situation where the name of the property and the
id in the configuration don't match. What if the IModelLocator instance described in the configuration has
an id called 'modelLocator' and for some reason this can't be easily changed?

29
The Inversion of
Control (IoC) container

Easy, you can define the exact name in the metadata as follows:

public class ExampleComponent extends UIComponent {

[Autowired(name='ModelLocator')]
public var modelInstance:IModelLocator;

public function ExampleComponent() {


super();
}

Note
When using the Autowired metadata do not forget to add these compiler settings to your Flex
project: -keep-as3-metadata += Autowired.

Apparently Flexbuilder on OSX behaves slightly different and needs you to add the metadata
one-by-one and quoted, like this: -keep-as3-metadata "Autowired".

Binding an object property to a property of an object in the


container
To keep your objects as decoupled as possible it might be preferred not to inject the modelInstance into
it, but just a certain property of the model. Since the data in the model is subject to change (usually it is
populated with data retrieved from remote method invocations), it would also be good to bind your view
to the model.

This can be achieved by using the following metadata:

public class ExampleProductListComponent extends UIComponent {

[Autowired(name='ModelLocator',property='products')]
public var products:ArrayCollection;

public function ExampleProductListComponent() {


super();
}

This example assumes that the ModelLocator object has a property called 'products' of type
ArrayCollection. A binding is established between these two objects, so when the products ArrayCollection
in the model in updated, so will the component.

The property value can also be a chain of objects, so this will work as well:

public class ExampleProductListComponent extends UIComponent {

[Autowired(name='ModelLocator',property='productManager.products')]
public var products:ArrayCollection;

public function ExampleProductListComponent() {

30
The Inversion of
Control (IoC) container

super();
}

Note
Since this functionality makes use of Flex binding it is therefore only available through the
FlexXMLApplicationContext.

Injecting an object property with an external property value


Its also possible to inject the value of an external property into a stage component. (If you want to know
more about external properties read the section 'External property files').

To do this add metadata to your source like this:

public class ExampleComponent extends UIComponent {

[Autowired(externalProperty='currentURL')]
public var websiteURL:String;

public function ExampleComponent() {


super();
}

Where the value of the propertyName metadata argument key matches the key in one of the loaded
property files.

Instantiating a Class with [Autowired] annotations


When a Class only uses [Autowired] annotations to define its dependencies it is a waste to have to add
an object definition for these classes to the XML configuration. Therefore its also possible to directly let
the application context instantiate the class:

var example:ExampleObject = applicationContext.createInstance(ExampleObject);

The createInstance() method will instantiate the Class and pass it through the rest of the wiring pipeline,
so also object post processing and metadata wiring.

Autowiring stage components


Spring Actionscript has one situation when used in conjunction with the Flex framework which differs from
other Spring implementations. This is when visual components (often declared as MXML components)
need to be autowired. In this case the container can't be responsible for the actual creation of the
components, so it is deferred back to the Flex application.

Concretely, we want to retain the expressiveness of MXML declaration and combine it with the IoC
capabilities of Spring Actionscript.

For example, given this (very simple) piece of MXML markup:

<?xml version="1.0" encoding="utf-8"?>

31
The Inversion of
Control (IoC) container

<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:custom="http://www.mydomain.com/flexcomponents"
layout="vertical">

<custom:OrderView myDependency="{this.applicationModel}"/>

</mx:Application>

In this case the application model instance is directly injected through concrete markup. In a lot of cases
this is perfectly acceptable, but Spring Actionscript offers a little extra flexibility by being able to inject
the model instance at runtime.

Spring Actionscript is able to perform these dependency injections by hooking an event listener into the
Event.ADDED_TO_STAGE event and process the components right after they have been added to the
stage.

To make use of the metadata processor that handles all of the functionality described in the following
sections add this to the XML configuration:

<object id="autowiringStageProcessor" class="org.springextensions.actionscript.stag

There are several ways of configuration for this stituation, in the following sections we will look at them
one by one.

Note
Spring Actionscript will wait until the container has finished loading and parsing its configuration,
after which it will loop through the entire current displaylist once to autowire the already created
stage components.

Note
If you'd like to learn more about the underlying architecture of stage wiring and how to extend
it, check out the section 'The IStageProcessor interface'.

Note
You can force the autowiring process to ignore the metadata on a given object by setting its skip-
metadata attribute to true. This will yield a small performance boost.

Autowiring stage components in a pure actionscript project


The FlexXMLApplicationContext take care all by itself of creating the necessary objects to facilitate stage
wiring. In a pure actionscript situation, however, a little bit of extra code is required. The stage wiring
system needs at one point to have a reference to the stage. In case of Flex this is easy, the SystemManager
singleton is used. In case of pure actionscript, the stage property will have to be set manually before any
XMLApplicationContext has been created. Add this code before the context's instantiation:

FlashStageProcessorRegistry.getInstance().stage = stage; //this being a valid refer


context = new XMLApplicationContext('application-context.xml');
context.addEventListener(Event.COMPLETE, completeHandler);
context.load();
//etc...

32
The Inversion of
Control (IoC) container

Autowiring stage components using XML configuration


Stage components can be configured using metadata that describes the desired injections, but this can also
be entirely expressed in XML metadata. Here is how to configure the ExampleComponent to be autowired
by type:

<object id="exampleComponent" class="classes.components.ExampleComponent" autowire=

In this example we assume that the ExampleComponent instance on the stage has an id with the value
exampleComponent.

Let us be clear immediately though, autowiring a stage component in this way is a bad idea. The Spring
Actionscript container will, in this case, actually loop through every property of the ExampleComponent
instance and try to find a matching wiring candidate in the container. This will very quickly become very
slow, so please regard this example as a proof of concept but don't use it in any actual production code.

Autowiring by name is almost the same and the same warning as the wiring by type is applicable: don't
do it.

<object id="exampleComponent" class="classes.components.ExampleComponent" autowire=

The most obvious way of configuring the ExampleComponent is by simply injecting the property explicitly
like this:

<object id="exampleComponent" class="classes.components.ExampleComponent" singleton


<property name="modelInstance" ref="ModelLocator"/>
</object>

Note
Do take notice of the singleton="false" attribute on each of these configuration examples.
Don't forget to add this value to each and every stage component definition entry. Spring
Actionscript defaults an object definition to a singleton scope and instantiates every singleton in
the configuration at startup. Failing to add the singleton="false" attribute will result in Spring
Actionscript creating a whole bunch of stage component instances unnecessarily.

How to determine which stage components are eligible for


configuration
The Event.ADDED_TO_STAGE event is fired a lot during the lifetime of a Flex application. It is
therefore paramount to make the event handler as efficient as possible and thus determine as quickly as
possible if the component in question is eligible for configuration or not.

Again Spring Actionscript offers several ways to do this. First of all we introduce the IObjectSelector
interface. This interface is a modest one:

public interface IObjectSelector {


function approve(object:Object):Boolean;
}

An object that implements this interface is responsible for determining whether a specific instance is
eligible for autowiring. The how and why is up to the implementation. Spring Actionscript by default uses
a FlexStageDefaultObjectSelector instance.

The FlexStageDefaultObjectSelector is a fairly simple implementation of the IObjectSelector interface


that, by default, rejects any component whose namespace starts with either 'flash.*' or 'mx.*', after that it

33
The Inversion of
Control (IoC) container

checks if the specified object inherits from UIComponent, if not, the object is rejected as well. (This is to
prevent embedded images in skins from clogging up the wiring pipeline).

Once a component is approved by the IObjectSelector it will be ready for configuration, the exact wiring
information will be determined by either reading the metadata or retrieving an object definition from the
configuration.

Naturally, Spring Actionscript also offers you the possibility to easily implement and plug in your own
IObjectSelector implementations. Let's have a look at how this works.

Creating and using a custom IObjectSelector implementation


By default the DefaultAutowiringStageProcessor is fitted with a FlexStageDefaultObjectSelector to
approve or reject stage components that have been added to the stage. To override this behaviour you
can create your own IObjectSelector implementation and add an object definition for it in the XML
configuration. A custom implementation might look something like this in your configuration:

<object id="flexStageObjectSelector" class="com.classes.objectselectors.MyCustomObj

To use this IObjectSelector instance you must also override the default autowiring processor with a new
instance and assign this object selector to it:

<object class="org.springextensions.actionscript.stage.DefaultAutowiringStageProces
<property name="objectSelector" ref="flexStageObjectSelector"/>
</object>

How to determine which object definition to use for which stage


component
Once a stage component is approved by an IObjectSelector instance the DefaultAutowiringStageProcessor
might need an object definition to be able to pass it on to the wire() method of the object factory (this
value can also be null, for the case where the components are solely configured with annotations). This
particular task is bestowed upon the IObjectDefinitionResolver interface. Like the IObjectSelector, this
interface is a simple one:

public interface IObjectDefinitionResolver {


function resolveObjectDefinition(object:*):IObjectDefinition;
}

An object that implements this interface is responsible for retrieving, or creating, an object definition for
a given object instance. Spring Actionscript by default offer the DefaultObjectDefinitionResolver class.
This implementation uses different strategies to retrieve the appropriate IObjectDefinition for an object.
First of all it uses the value of its objectIdProperty property to find the object definition by name. By
default the value of this property is 'name'. This means that if a stage component is being examined whose
name property has a value of 'MyStageComponent', the DefaultObjectDefinitionResolver will look for
an object definition with an id of 'MyStageComponent'. If the object definition can't be found it will
fall back on trying to find an object definition by type, but only if the lookupByType property on the
DefaultObjectDefinitionResolver is set to true.

If both of these options fail the DefaultObjectDefinitionResolver will return null. This will happen in the
case that a stage component has been decorated with autowiring metadata and has no further use for an
object definition. Of course, the both can combined as well, but its open to discussion whether this is
advisable. To use the DefaultObjectDefinitionResolver use this XML configuration:

<object class="org.springextensions.actionscript.stage.DefaultAutowiringStageProces
<property name="objectDefinitionResolver">

34
The Inversion of
Control (IoC) container

<object id="defaultObjectDefinitionResolver"
class="org.springextensions.actionscript.stage.DefaultObjectDefinitionResolve
</property>
</object>

Just like the IObjectSelector its also possible to plug in your own IObjectDefinitionResolver
implementation. What follows is how to do this.

Creating and using a custom IObjectDefinitionResolver implementation


By default the DefaultAutowiringStageProcessor is fitted with a DefaultObjectDefinitionResolver to
retrieve an appropriate IObjectDefinition instance for a given object. To override this behaviour you can
create your own IObjectDefinitionResolver implementation and add an object definition for it in the XML
configuration. So you can simply add your IObjectDefinitionResolver implementation as follows:

<object id="flexStageObjectDefinitionResolver" class="com.classes.definitionresolve

To use this IObjectDefinitionResolver instance you must also override the default autowiring processor
with a new instance and assign this object selector to it:

<object class="org.springextensions.actionscript.stage.DefaultAutowiringStageProces
<property name="objectSelector" ref="flexStageObjectSelector"/>
<property name="objectDefinitionResolver" ref="flexStageObjectDefinitionResolver"
</object>

Optimizing the stage component selection process


The Event.ADDED_TO_STAGE that is being used by the stage wiring system gets dispatched a LOT
in the lifetime of a Flex application. It is therefore paramount to keep the selection and wiring process as
optimized as possible. First of all it is recommended to use a custom IObjectSelector as much as possible.
The one created by default by the DefaultAutowiringStageProcessor, the FlexStageDefaultObjectSelector,
uses this code for the selection process:

public function approve(object:Object):Boolean {

var className:String;
try {
className = getQualifiedClassName(object);
} catch (e:*) {
return false;
}

if (className.search("^spark.*") > -1 || className.search("^flash.*") > -1 || cla


return false;
}

if (!(object is UIComponent)) {
return false;
}

try {
ObjectUtils.getClass(object);
return true;
} catch (e:*) {
}

35
The Inversion of
Control (IoC) container

return false;
}

These are quite a few calls for every component being added to the stage. Now, imagine a situation
where you know beforehand that only components that implement a specific marker interface need to be
autowired. In that case you can implement a much simpler selection process. Let's say the marker interface
is called IAutowiredComponent, then the implementation of the approve() method needs to be simply this:

public function approve(object:Object):Boolean {


return (object is IAutowiredComponent);
}

Injecting stage components into other objects


It is also possible to inject a stage component into a 'regular' object. To achieve this Spring Actionscript
offers an IStageProcessor implementation called GenericStageProcessor. What this stageprocessor does is
it will assign a component that was added to the stage to a previously configured object. This assignment
can either be done by property assignement or method invocation.

To determine which object will 'receive' the selected components the GenericStageProcessor has a property
called targetObject. This targetObject is a reference to another object that is declared in the application
context, so to configure the GenericStageProcessor you will need to add this markup to your application
context:

<object class="org.springextensions.actionscript.stage.GenericStageProcessor" id="s


<property name="targetObject" ref="stageComponentRegistry"/>
</object>

Let's say this stageComponentRegistry object has a method called registerComponent that is used to
gather a list of stage components. To have the GenericStageProcessor invoke this method with each stage
component it approves, add this bit of markup:

<object class="org.springextensions.actionscript.stage.GenericStageProcessor" id="s


<property name="targetObject" ref="stageComponentRegistry"/>
<property name="targetMethod" value="registerComponent"/>
</object>

Right, that was easy so far. Now all we need to do is put the mechanism in place that will
determine which stage components will be passed to the stageComponentRegistry instance. For this
we need to declare an IObjectSelector instance, in this example we use one of the pre-existing
implementations offered by Spring Actionscript called ClassBasedObjectSelector. This IObjectSelector
approves objects based on their classname and uses regular expressions to evaluate these names. To add
the ClassBasedObjectSelector to your application add this markup:

<object class="org.springextensions.actionscript.ioc.wire.ClassBasedObjectSelector"
<property name="approveOnMatch" value="true"/>
<property name="classRegexpArray">
<value>
<array>
<value>com\.components*</value>
</array>
</value>
</property>
</object>

36
The Inversion of
Control (IoC) container

Change the regular expression pattern to suit your own needs.

After this all we need to do is assign this selector to the GenericStageProcessor like this:

<object class="org.springextensions.actionscript.stage.GenericStageProcessor" id="s


<property name="targetObject" ref="stageComponentRegistry"/>
<property name="targetMethod" value="registerComponent"/>
<property name="objectSelector" ref="registrySelector"/>
</object>

And that's it, from now on every component that is added to the stage and has a class name that starts with
com.components will be passed to the registerComponent method of the stageComponentRegistry object.

To make life a little easier by reducing the amount of markup for the GenericStageProcessor Spring
Actionscript also offers a custom namespace with some special markup for this class. See The Stage
Processing schema for more details.

Implementing custom autowiring support using the


IAutowireProcessor interface
Spring Actionscript wouldn't be Spring Actionscript if it didn't allow you to implement your own brand
of autowiring. Naturally the Spring Actionscript team is of the opinion that the offered autowiring
functionality is about as broad as one can imagine, but should the need arise to step outside the confines
of Spring Actionscript autowiring than this entirely possible.

In this particular case the IAutowireProcessor is your friend. And as you are used to, its not a very
complicated one, see for yourself:

public interface IAutowireProcessor {

function autoWire(object:Object, objectDefinition:IObjectDefinition, objectName:St

function preprocessObjectDefinition(objectDefinition:IObjectDefinition):void;
}

The first method is the main autoWire() method that is invoked by the object container immediately after
creation. (see 'A graphical overview of the wiring flow of an object' for more details.)

The second method is invoked by the container right before an object is actually created, so this would
typically be a good moment to change any kind of constructor argument autowiring or perhaps change the
autowiring strategy of the current IObjectDefinition based on some pre-configured logic.

As you can see in the default implementation used by the AbstractObjectFactory, (fittingly titled
DefaultAutowireProcessor),it is also possible for your own IAutowireProcessor implementation to
include the IObjectFactoryAware interface. If your instance implements this particular interface it will
automatically be injected by the object factory instance to which the IAutowireProcessor is assigned.

Now, after you've created your own implementation, its time to hook it up to the object container, typically
this would be done something like this:

var xmlApplicationContext:XMLApplicationContext = new XMLApplicationContext();


xmlApplicationContext.autowireProcessor = new MyCustomAutowireProcessor();

After that your own autowiring logic will be performed on any object created by the
XMLApplicationContext instance.

37
The Inversion of
Control (IoC) container

Note
Consequently, when you don't need the autowiring functionality at all in your application, it might
be an idea to set the autowireProcessor property to null as this will yield a small performance
benefit.

The IStageProcessor interface


The underlying architecture for stage component wiring can be easily extended, the basics
are very simple: An IStageProcessorRegistry implementation (in most cases that would be the
FlexXMLApplicationContext) adds an event listener to the SystemManager and listens for an
Event.ADDED_TO_STAGE event to be fired. After that an IObjectSelector instance determines whether
the DefaultAutowiringStageProcessor should process the object or not.

Here's a quick overview of how the IStageProcessorRegistry, IObjectSelector and IStageProcessor


interfaces work together:

This pattern can naturally be used to perform other kinds of operations on stage components.

Note
To automatically register any IStageProcessor instances declared in the configuration, a
FlexXMLApplicationContext instance creates a StageProcessorFactoryPostprocessor for itself.

As you can see the DefaultAutowiringStageProcessor is an implementation of the IStageProcessor


interface, this interface is, as usual, fairly simple:

public interface IStageProcessor {

function get selector():IObjectSelector;

function set selector(value:IObjectSelector):void;

function process(object:Object):Object;
}

The IObjectSelector instance can be shared among IStageProcessor instances, so that way only one
IObjectSelector's approval can invoke multiple IStageProcessor process() methods. So, if you want
the same IObjectSelector to also trigger your custom IStageProcessor, add their configurations like this:

<object class="org.springextensions.actionscript.ioc.wire.ClassBasedObjectSelector"
<property name="approveOnMatch" value="true"/>
<property name="classRegexpArray">
<value>
<array>
<value>com\.components*</value>
</array>
</value>
</property>
</object>

<object class="org.springextensions.actionscript.stage.DefaultAutowiringStageProces
<property name="objectSelector" ref="globalSelector"/>

38
The Inversion of
Control (IoC) container

<property name="objectDefinitionResolver" ref="flexStageObjectDefinitionResolver"


</object>

<object class="com.classesMyCustomStageProcessor" id="myCustomStageProcessor">


<property name="objectSelector" ref="globalSelector"/>
</object>

Although probably you will need different approval strategies for each IStageProcessor instance, in that
case declare separate IObjectSelector instances per IStageProcessor.

Note
For another example of an IStageProcessor implementation, see the section 'Injecting stage
components into other objects'.

The LocalizationStageProcessor class


A good example of an IStageProcessor implementation is the LocalizationStageProcessor, found in the
package. This class enables you to assign resource values to stage components at runtime based on the
value of the component's id. To use this class add this bit of markup to your configuration:

<object id="resourceManager" class="mx.resources.ResourceManager" factory-method="g

<object id="localizationProcessor" class="org.springextensions.actionscript.localiz


<property name="resourceManager" ref="resourceManager"/>
<property name="bundleName" value="mySampleResources"/><!-- change this to the nam
</object>

The LocalizationStageProcessor uses a PropertyValueBasedObjectSelector instance by default, this


selector approves only components whose id property is set. When the LocalizationStageProcessor
receives a component it will use its id as a base name to look up resource strings and assign these to arbitrary
properties on the component. For instance, if a button is added to the stage with an id called 'myButton'
and you want the label property on the button to be set to 'Click me' add a resource string like this:

myButton_label=Click me

If you want the tooltip property to be set to 'Click this button for fun!', then add a resource string like this:

myButton_toolTip=Click this button for fun!

By default the LocalizationStageProcessor looks for resource strings for the following property names:
text, label, toolTip, prompt, dataProvider, title, headerText.

To add to this list, or replace it with your own array of names, use the LocalizationStageProcessor's
resourceSuffixes property.

There is a sample project that demonstrates the LocalizationStageProcessor class, you can take a look by
following this .

Note
To learn more about flex resource management, follow this .

The SimpleSecurityStageProcessor class


The stage processing pattern can also be used to add role and rights based security to an
application. For this specific task Spring Actionscript offers the package. Part of this package is the

39
The Inversion of
Control (IoC) container

SimpleSecurityStageProcessor which is able to create a SimpleStageSecurityManager for specified


components after they have been added to the stage.

To add the SimpleSecurityStageProcessor to your configuration add this bit of markup:

<object id="securityProcessor" class="org.springextensions.actionscript.security.Si

Now just adding this stage processor to your application context isn't going to achieve much. Somehow
the data needed to create what kind of SimpleStageSecurityManager for which stage component needs to
be fed to the stage processor.

The SimpleSecurityStageProcessor creates a SimpleSecurityManagerFactory instance for itself by default,


this ISecurityManagerFactory implementation uses a Dictionary of MembershipAccessData to hold the
membership information for stage components. The key of the Dictionary is the id of the stage component
to which the MembershipAccessData is applicable. The MembershipAccessData determines which roles
and rights are applicable and what strategy is to be used to restrict access to the component.

For example, to assign the right called 'canClickButton' to a Button instance with the id 'myButton' and to
have the button be invisible when access is restricted, create a MembershipAccessData instance like this:

var md:MembershipAccessData = new MembershipAccessData();


md.rights.push("canClickButton");
md.accessStrategy = AccessStrategy.VISIBLE;

To have this membership data be used by the stage processor, assign it like this:

var sp:SimpleSecurityStageProcessor = _applicationContext.getObject("securityProces


(sp.securityManagerFactory as SimpleSecurityManagerFactory).membershipData["myButto

This will cause the SimpleSecurityStageProcessor to create a SimpleSecurityManager instance for the
button instance with id 'myButton' after it has been added to the stage.

Finally, the SimpleSecurityManagerFactory needs an IMembershipOwner instance to evaluate against.


Typically this would be a user object representing the currently logged in user. The IMembershipOwner
interface is a modest one and only exposes two properties: rights and roles:

public interface IMembershipOwner extends IEventDispatcher {

function get roles():Array;


[Bindable(event="rolesChanged")]
function set roles(value:Array):void;

function get rights():Array;


[Bindable(event="rightsChanged")]
function set rights(value:Array):void;

You can either have your user object implement this interface or simple inherit from the Spring Actionscript
SimpleMembershipOwner class.

Lastly, it is necessary to assign the user object to the ISecurityManagerFactory that the stage processor
exposes. This enables the ISecurityManagers to determine whether they will grant access to their stage
components for the currently logged in user, based on the roles and rights that this user owns.

You can perform this assignment like so:

40
The Inversion of
Control (IoC) container

var sp:SimpleSecurityStageProcessor = _applicationContext.getObject("securityProces


sp.securityManagerFactory.membershipOwner = currentUser; //Where the currentUser va

And that's it! If the currentUser also owns the right called 'canClickButton' the button with id 'myButton'
will become visible after the sp.securityManagerFactory.membershipOwner = currentUser assignment
has been performed.

To simulate the user logging out simply set the membershipOwner property to null.

Note
There is a sample project that demonstrates the SimpleSecurityStageProcessor class, you can take
a look by following this .

The IStageDestroyer interface


The IStageProcessor interface also has a counterpart called the IStageDestroyer interface. Implementations
of this interface aim to process a component after it has been removed from the stage. The
DefaultAutowiringStageProcessor class is also an implementation of this interface and can be used to
invoke disposal methods on a stage components after its been removed. The interface is an extension of
IStageProcessor and adds only one method:

public interface IStageDestroyer extends IStageProcessor {


function destroy(object:Object):Object;
}

Implementations can check for interfaces or methods or perform other logic which will eventually help
the specified object to become eligible for garbage collection. See 'Destroying stage components' to find
out how the DefaultAutowiringStageProcessor goes about this.

A graphical overview of the initialization of the


FlexXMLApplicationContext

Customizing the nature of an object


Initialization callbacks
Object definitions provide support for a generic initialization method to be specified. In the case of XML-
based configuration metadata, this is done using the 'init-method' attribute. For example, the following
definition:

<object id="exampleInitObject" class="examples.ExampleObject" init-method="init"/>

public class ExampleObject {

public init():void {
// do some initialization work
}
}

...is exactly the same as...

41
The Inversion of
Control (IoC) container

<object id="exampleInitObject" class="examples.ExampleObject">


<method-invocation name="init"/>
</object>

But a whole lot shorter...

Knowing who you are


IApplicationContextAware
A class which implements the IApplicationContextAware interface is provided with a reference to the
FlexXMLApplicationContext or XMLApplicationContext that created it, when it is created by that
ApplicationContext.

public interface IApplicationContextAware {

function set applicationContext(value:IApplicationContext):void;

This allows objects to manipulate the FlexXMLApplicationContext or XMLApplicationContext that


created them programmatically, through the IApplicationContextAware interface, or by casting the
reference to a known subclass of this which exposes additional functionality. Primarily this would consist
of programmatic retrieval of other objects. While there are cases when this capability is useful, it should
generally be avoided, since it couples the code to Spring Actionscript and does not follow the Inversion
of Control style, where collaborators are provided to objects as properties.

Object definition inheritance


An object definition potentially contains a large amount of configuration information, including container
specific information (for example initialization method, static factory method name, and so forth) and
constructor arguments and property values. A child object definition is an object definition that inherits
configuration data from a parent definition. It is then able to override some values, or add others, as needed.
Using parent and child objects definitions can potentially save a lot of typing. Effectively, this is a form
of templating.

When working with an IApplicationContext programmatically, child object definitions are represented by
the ChildObjectDefinition class. Most users will never work with them on this level, instead configuring
object definitions declaratively. When using XML-based configuration metadata a child object definition
is indicated simply by using the 'parent' attribute, specifying the parent object as the value of this attribute.

<object id="inheritedTestObject" abstract="true" class="org.springactionscript.obje


<property name="name" value="parent"/>
<property name="age" value="1"/>
</object>

<object id="inheritsWithDifferentClass"
class="org.springactionscript.objects.DerivedTestObject"
parent="inheritedTestObject" init-method="initialize">

<property name="name" value="override"/>


<!-- the age property value of 1 will be inherited from parent -->
</object>

42
The Inversion of
Control (IoC) container

A child object definition will use the object class from the parent definition if none is specified, but can
also override it. In the latter case, the child object class must be compatible with the parent, that is it must
accept the parent's property values.

A child object definition will inherit constructor argument values, property values and method overrides
from the parent, with the option to add new values. If any init-method and/or static factory method settings
are specified, they will override the corresponding parent settings.

The remaining settings will always be taken from the child definition: depends on, autowire mode,
dependency check, singleton, scope, lazy init.

Note that in the example above, we have explicitly marked the parent object definition as abstract by
using the abstract attribute. In the case that the parent definition does not specify a class, and so explicitly
marking the parent object definition as abstract is required:

<object id="inheritedTestObject" abstract="true">


<property name="name" value="parent"/>
<property name="age" value="1"/>
</object>

<object id="inheritsWithDifferentClass"
class="org.springactionscript.objects.DerivedTestObject"
parent="inheritedTestObject" init-method="initialize">

<property name="name" value="override"/>


<!-- the age property value of 1 will be inherited from parent -->
</object>

The parent object cannot get instantiated on its own since it is incomplete, and it is also explicitly
marked as abstract. When a definition is defined to be abstract like this, it is usable only as a pure
template object definition that will serve as a parent definition for child definitions. Trying to use such
an abstract parent object on its own (by referring to it as a ref property of another object, or doing an
explicit getObject() call with the parent object id), will result in an error. Similarly, the container's internal
preInstantiateSingletons() method will completely ignore object definitions which are defined as abstract.

Note
ApplicationContexts will by default pre-instantiate all singletons. Therefore it is important (at
least for singleton objects) that if you have a (parent) object definition which you intend to use
only as a template, and this definition specifies a class, you must make sure to set the 'abstract'
attribute to 'true', otherwise the application context will actually (attempt to) pre-instantiate the
abstract object.

Spring Actionscript offers a second way of defining a template which is almost identical to the above way.
There is a specific element called that offers the same kind of functionality but also has a way of adding
parameters to the template's definition. Let's take a look at the following XML metadata:

<template id="remoteObject">
<object class="mx.rpc.remoting.mxml.RemoteObject">
<property name="destination" value="ColdFusion"/>
<property name="endpoint" value="/flex2gateway/"/>
<property name="concurrency" value="multiple"/>
<property name="makeObjectsBindable" value="${makeBindable}"/>
<property name="showBusyCursor" value="${showCursor}"/>
<property name="source" value="com.path.to.remoteobjects.${serviceClass}"/>

43
The Inversion of
Control (IoC) container

<property name="channelSet">
<ref>channelset</ref>
</property>
</object>
</template>

This shows the definition of a RemoteObject template which can be re-used for creating different instances
of a RemoteObject with different parameters. In the XML metadata you can see a number of placeholders
recognizable by the fact that they are enclosed by braces and prefixed with a dollar-sign like this:
${placeholder}. These placeholders will be replaced by the values of the parameters that are sent to the
template when instantiating an object.

Here is an example of an object definition that makes use of the template described above:

<object id="concreteService" template="remoteObject">


<param name="makeBindable" value="false"/>
<param name="showCursor" value="true"/>
<param name="serviceClass" value="gatewayname"/>
</object>

Note
The class that takes care of this functionality is the TemplatePreprocessor, this class is
automatically created by the XMLObjectDefinitionsParser in its preProcessXML() method.

Handling object inheritance using interfaces


Another way of defining object configurations is by using the interfaces they might implement. Imagine
several classes implementing the same interface, if only one interface is implemented then using an object
definition with an 'abstract="true"' attribute and having all implementing object definitions refer to this
definition with their 'parent' attribute would suffice, even a template would do.

However, when multiple interfaces are being implemented is when you hit the limitations of these
configuration options. In this case the element might be able to help you out and in this section we will
explain how.

Let's make up two simple interfaces for this example:

public interface ISimpleInterface {


function get myStringProperty():String;
function set myStringProperty(value:String):void;
}

public interface ISimpleInitializingInterface {


function initialize():void;
}

These interfaces can be configured in the XML configuration like this:

<interface class="com.mycompany.interfaces.ISimpleInterface">
<property name="myStringProperty" value="This is my test value!"/>
</interface>

<interface class="com.mycompany.interfaces.ISimpleInitializingInterface" init-metho

44
The Inversion of
Control (IoC) container

Now, imagine creating a class that implements the aforementioned ISimpleInterface:

public class MySimpleClass implements ISimpleInterface {


//implementation omitted
}

To configure this object in your XML markup all you need to do is declare the object:

<object id="mySimpleInstance" class="com.mycompany.classes.MySimpleClass"/>

Afterwards Spring Actionscript will take care of combining the configurations for the implemented
interfaces with your object definition.

This works for multiple interfaces as well, so another class that would implement both interfaces. Say,
something like this:

public class MySimpleInitializingClass implements ISimpleInterface, ISimpleInitiali


//implementation omitted
}

To receive a fully configured instance of this object, all you need to do again is simply declare the object
like this:

<object id="mySimpleInitialzingInstance" class="com.mycompany.classes.MySimpleIniti

And in this case Spring Actionscript will have combined the configurations for the ISimpleInterface and
ISimpleInitializingInterface and added it to the mySimpleInitialzingInstance configuration.

Note
The class that takes care of this functionality is the InterfacePreprocessor, this class is
automatically created by the XMLObjectDefinitionsParser in its preProcessXML() method.

Object scopes
When you create an object definition what you are actually creating is a recipe for creating actual instances
of the class defined by that object definition. The idea that an object definition is a recipe is important,
because it means that, just like a class, you can potentially have many object instances created from a
single recipe.

You can control not only the various dependencies and configuration values that are to be plugged into
an object that is created from a particular object definition, but also the scope of the objects created from
a particular object definition. This approach is very powerful and gives you the flexibility to choose the
scope of the objects you create through configuration instead of having to 'bake in' the scope of an object
at the Actionscript class level. Objects can be defined to be deployed in one of a number of scopes: out of
the box, Spring Actionscript supports exactly two scopes.

The scopes supported out of the box are listed below:

Table 2.4. Object scopes


Scope Description
singleton Scopes a single object definition to a single object
instance per Spring Actionscript IoC container.

45
The Inversion of
Control (IoC) container

prototype Scopes a single object definition to any number of


object instances.

The singleton scope


When an object is a singleton, only one shared instance of the object will be managed, and all requests
for objects with an id matching that object definition will result in that one specific object instance being
returned by the Spring Actionscript container.

To put it another way, when you define an object definition and it is scoped as a singleton, then the Spring
Actionscript IoC container will create exactly one instance of the object defined by that object definition.
This single instance will be stored in a cache of such singleton objects, and all subsequent requests and
references for that named object will result in the cached object being returned.

Please be aware that Spring Actionscript's concept of a singleton object is quite different from the Singleton
pattern as defined in the seminal Gang of Four (GoF) patterns book. The GoF Singleton hard codes the
scope of an object such that one and only one instance of a particular class will ever be created. The scope
of the Spring Actionscript singleton is best described as per container and per object. This means that
if you define one object for a particular class in a single Spring Actionscript container, then the Spring
Actionscript container will create one and only one instance of the class defined by that object definition.
The singleton scope is the default scope in Spring Actionscript. To define an object as a singleton in XML,
you would write configuration like so:

<object id="accountService" class="com.foo.DefaultAccountService"/>

<!-- the following is equivalent, though redundant (singleton scope is the default)
<object id="accountService" class="com.foo.DefaultAccountService" scope="singleton"

<!-- the following is equivalent and preserved for backward compatibility -->
<object id="accountService" class="com.foo.DefaultAccountService" singleton="true"/

The prototype scope


The non-singleton, prototype scope of object deployment results in the creation of a new object instance
every time a request for that specific object is made (that is, it is injected into another object or it is
requested via a programmatic getObject() method call on the container). As a rule of thumb, you should
use the prototype scope for all objecs that are stateful, while the singleton scope should be used for stateless
objects.

To define an object as a prototype in XML, you would write configuration like so:

<!-- recommended markup -->


<object id="accountService" class="com.foo.DefaultAccountService" scope="prototype"

<!-- the following is equivalent and preserved for backward compatibility -->
<object id="accountService" class="com.foo.DefaultAccountService" singleton="false"

Singleton objecs with prototype-object dependencies


When using singleton-scoped objects that have dependencies on objects that are scoped as prototypes,
please be aware that dependencies are resolved at instantiation time. This means that if you dependency
inject a prototype-scoped object into a singleton-scoped object, a brand new prototype object will be
instantiated and then dependency injected into the singleton object... but that is all. That exact same
prototype instance will be the sole instance that is ever supplied to the singleton-scoped object, which is
fine if that is what you want.

46
The Inversion of
Control (IoC) container

However, sometimes what you actually want is for the singleton-scoped object to be able to acquire a
brand new instance of the prototype-scoped bean again and again and again at runtime. In that case it is no
use just dependency injecting a prototype-scoped object into your singleton object, because as explained
above, that only happens once when the Spring Actionscript container is instantiating the singleton object
and resolving and injecting its dependencies.

Customizing the nature of an object


Lifecycle callbacks
The Spring Actionscript Framework provides a callback interface to change the behavior of your object
in the container; this is the IInitializingObject interface. Implementing this interface will result in the
container calling the afterPropertiesSet() method immediately after the object has been created and
configured, but before its initialization method is called (defined by the init-method attribute).

Internally, the Spring Actionscript Framework uses IObjectPostProcessor implementations to process


any callback interfaces it can find and call the appropriate methods. If you need custom features
or other lifecycle behavior Spring Actionscript doesn't offer out-of-the-box, you can implement an
IObjectPostProcessor yourself. More information about this can be found in the section entitled .

Initialization callbacks
Implementing the org.springextensions.actionscript.ioc.factory.IInitializingObject interface allows an
object to perform initialization work after all necessary properties on the object have been set by the
container. The IInitializingObject interface specifies exactly one method:

function afterPropertiesSet():void;

Generally, the use of the IInitializingObject interface can be avoided and is actually discouraged since
it unnecessarily couples the code to Spring Actionscript. As an alternative, objects definitions provide
support for a generic initialization method to be specified. In the case of XML-based configuration
metadata, this is done using the 'init-method' attribute. For example, the following definition:

<object id="exampleInitObject" class="examples.ExampleObject" init-method="init"/>

public class ExampleObject {

public function init():void {


// do some initialization work
}
}

...is exactly the same as...

<object id="exampleInitObject" class="examples.AnotherExampleObject"/>

public class AnotherExampleObject implements IInitializingObject {

public function afterPropertiesSet():void {


// do some initialization work
}
}

... but does not couple the code to Spring Actionscript.

47
The Inversion of
Control (IoC) container

Container extension points


The IoC component of the Spring Actionscript Framework has been designed for extension. There is
typically no need for an application developer to subclass the ApplicationContext class. The Spring
Actionscript IoC container can be infinitely extended by plugging in implementations of special integration
interfaces.

Spring Actionscript can be extended through the IObjectPostProcessor, IObjectFactoryPostProcessor and


IFactoryObject interfaces.

First we look at some existing examples of these interfaces and after that there is a small tutorial on how
to build your own implementation.

The following are a few implementations of these interfaces that Spring Actionscript supports 'out of the
box' to help you out in daily development life.

Flex application settings


Specifically for the FlexXMLApplicationContext there is the ability to refer to the properties of the
Application class directly from the container's metadata. These properties can be used as regular property
placeholders in an application context or a properties file. e.g. ${application.url}.

The following properties are supported:

• application.frameRate

• application.historyManagementEnabled

• application.pageTitle

• application.resetHistory

• application.scriptRecursionLimit

• application.scriptTimeLimit

• application.url

• application.url.protocol

• application.url.host

• application.url.port

• application.usePreloader

• application.viewSourceURL

• application.parameters (when they exist)

Individual flashvars are automatically added to the application settings, so if a flashvar called myFlashVar
is passed to the application it will be available as application.myFlashVar in the context.

Logging target factory


The logging target this factory creates will automatically be added to the log manager class.

<object id="traceTarget" class="org.springextensions.actionscript.ioc.factory.confi

48
The Inversion of
Control (IoC) container

<property name="loggingTargetClass" value="mx.logging.targets.TraceTarget"/>


<property name="includeCategory" value="true"/>
<property name="includeDate" value="true"/>
<property name="includeLevel" value="true"/>
<property name="includeTime" value="true"/>
<property name="level" value="2"/>
<property name="filters">
<array>
<value>com.domain.model.*</value>
<value>com.domain.view.*</value>
</array>
</property>
</object>

Enforcing required property injections


This is an IObjectPostProcessor implementation that enforces required properties to be injected. A property
is marked as required by adding [Required] metadata to the property definition:

[Required]
public var myProperty:Type;

If the property has been defined as required but a suitable injection candidate cannot be found by the
container it will throw an IllegalArgumentError exception.

In order to use it in your application, include it as an object in your application context:

<object class="org.springextensions.actionscript.ioc.factory.config.RequiredMetadat

Injecting the object factory


The ObjectFactoryAwarePostProcessor will check if the object that has just been created by the container
implements the IObjectContainerAware interface. If this is found to be true it will inject the container as
a property on the specified object.

In order to use it in your application, include it as an object in your application context:

<object class="org.springextensions.actionscript.ioc.factory.config.ObjectFactoryAw

Injecting fields from other objects


Sometimes it is necessary to use the value of another object's field to be injected into a new object. Spring
Actionscript offers the FieldRetrievingFactoryObject the this specific task. Configuration for this object
is fairly straightforward, here is an example of its usage:

<object id="trafficEventManager" class="com.myclasses.TrafficEventManager">


<constructor-arg>
<object class="org.springextensions.actionscript.ioc.factory.config.FieldRetrievi
<property name="targetObject" ref="modelLocator" />
<property name="targetField" value="trafficEventTypes" />
</object>
</constructor-arg>
</object>

The TrafficEventManager instance requires an ArrayCollection of event types to be passed to its


constructor. In this example we assume this list of event types is defined in the modelLocator

49
The Inversion of
Control (IoC) container

instance by its trafficEventTypes property. With the above example this value is now injected into the
TrafficEventManager's constructor.

Note
The FieldRetrievingFactoryObject supports both instance and static properties.

Here's how the FieldRetrievingFactoryObject can be used to retrieve a static field:

<object class="org.springextensions.actionscript.ioc.factory.config.FieldRetrieving
<property name="staticField" value="CURRENT_VERSION"/>
<property name="targetClass" value="mx.core.FlexVersion/>
</object>

Injecting method invocation results from other objects


Not just properties can be retrieved from other objects, also the result of method invocations on these
objects can be used to inject into other objects. The MethodInvokingFactoryObject deals with these kinds
of situations. Here is an example:

<object class="org.springextensions.actionscript.ioc.factory.config.MethodInvokingF
<property name="targetClass" value="mx.resources.ResourceManager"/>
<property name="targetMethod" value="getInstance"/>
</object>

This will call the static getInstance() method on the mx.resources.ResourceManager class. It is also
possible to call a method on an instance, here's how:

<object class="org.springextensions.actionscript.ioc.factory.config.MethodInvokingF
<property name="targetObject" value="resourceManager"/>
<property name="targetMethod" value="getString"/>
<property name="arguments">
<array>
<value>bundleName</value>
<value>resourceName</value>
</array>
</property>
</object>

This will retrieve the previously instantiated resourceManager from the first example and invokes the
getString() method on it using the specified array of arguments.

Customizing objects using ObjectPostProcessors


The first extension point that we will look at is the IObjectPostProcessor interface. This interface defines
a number of callback methods that you as an application developer can implement in order to provide
your own (or override the containers default) instantiation logic, dependency-resolution logic, and so forth.
If you want to do some custom logic after the Spring Actionscript container has finished instantiating,
configuring and otherwise initializing an object, you can plug in one or more IObjectPostProcessor
implementations.

Note
IObjectPostProcessors operate on object instances; that is to say, the Spring Actionscript IoC
container will have instantiated an object instance for you, and then IObjectPostProcessors get a

50
The Inversion of
Control (IoC) container

chance to do their stuff. If you want to change the actual object definition (that is the recipe that
defines the object), then you rather need to use a IObjectFactoryPostProcessor (described below
in the section entitled .

The org.springextensions.actionscript.ioc.factory.config.IObjectPostProcessor interface consists of


exactly two callback methods. When such a class is registered as a post-processor with the container,
for each object instance that is created by the container, the post-processor will get a callback from the
container both before any container initialization methods (such as afterPropertiesSet and any declared
init method) are called, and also afterwards. The post-processor is free to do what it wishes with the object
instance, including ignoring the callback completely. An object post-processor will typically check for
callback interfaces, or do something such as wrap an object with a proxy.

An ApplicationContext will automatically detect any objects which are defined in the configuration
metadata which is supplied to it that implement the IObjectPostProcessor interface, and register them as
post-processors, to be then called appropriately by the container on object creation. Nothing else needs to
be done other than deploying the post-processors in a similar fashion to any other object.

Note
You can force the object factory to ignore its list of IObjectPostProcessors for a given
ObjectDefinition by setting its skip-postprocessors attribute to true. This will yield a small
performance boost.

Creating a postprocessor
Let's see how we can build our own processor. Suppose we have an IProductManager interface that looks
like this:

public interface IProductManager {

function get items():ArrayCollection;


function set items(value:ArrayCollection):void;
}

At runtime the actual items will be loaded by a server call and stored in the application model. Since we
won't know exactly when the items will be loaded we can't use the FieldRetrievingFactoryObject to simply
assign the model's items to the items property of the IProductManager instance. What we'd like to do is
actually bind the productmanager's items to the model items.

Let's see if we can build something that performs this task. We will implement the IObjectPostProcessor
interfaces like this:

public class PropertyBindingPostProcessor implements IObjectPostProcessor {

public function PropertyBindingPostProcessor() {


super();
}

private var _host:Object;


public set host(value:Object):void {
_host = host;
}
private var _chain:Object;
public set chain(value:Object):void {
_chain = value;

51
The Inversion of
Control (IoC) container

public function postProcessBeforeInitialization(object:*, objectName:String):* {


Assert.notNull(_host,"host property cannot be null");
Assert.notNull(_chain,"chain property cannot be null");
if (object is IProductManager)
{
BindingUtils.bindProperty(object,'items',host,chain);
}
}

public function postProcessAfterInitialization(object:*, objectName:String):* {


return null;
}

Now all we need to do is add this bit of configuration and the post processor is ready to do its work:

<object id="propertyBindingPostProcessor" class="com.myclasses.postprocessors.Prope


<property name="host" ref="modelInstance"/>
<property name="chain" value="items"/>
</object>

That's it basically it! Now its certainly possible to come up with a much more generic solution than this,
but it does show its fairly easy to create your own post processors for specific tasks.

Customizing instantiation logic using the IFactoryObject interface


The org.springextensions.actionscript.ioc.factory.IFactoryObject interface is to be implemented by objects
that are themselves factories.

The IFactoryObject interface is a point of pluggability into the Spring Actionscript IoC containers
instantiation logic. If you have some complex initialization code that is better expressed in Actionscript
as opposed to a (potentially) verbose amount of XML, you can create your own IFactoryObject, write the
complex initialization inside that class, and then plug your custom IFactoryObject into the container.

Now when you request an instance of such an IFactoryObject from the container, it doesn't actually
return an IFactoryObject instance, instead, it calls the getObject() method on the object and returns the
result of this method.

The IFactoryObject interface provides three methods:

• getObject():*; has to return an instance of the object this factory creates. The instance can possibly be
shared (depending on whether this factory returns singletons or prototypes).

• isSingleton():Boolean; has to return true if this IFactoryObject returns singletons, false otherwise

• getObjectType():Class; has to return either the object type returned by the getObject() method or null
if the type isn't known in advance

Let's say we need to instantiate an object of class IncrediblyComplicatedObject. The initialization of this
object involves some kind of logic that is beyond the scope of Spring Actionscript and way too complicated
to be expressed in XML. We are of course able to write our own code to perform this. We can now build
an IFactoryObject that implements this task:

52
The Inversion of
Control (IoC) container

public class IncrediblyComplicatedObjectFactory implements IFactoryObject {

public function getObject():* {


var instance:IncrediblyComplicatedObject = new IncrediblyComplicatedObject();
//creation logic ommitted
return instance;
}

public function getObjectType():Class {


return IncrediblyComplicatedObject;
}

public function get isSingleton():Boolean {


return false;
}

The isSingleton() method returns false, this means that every time this IFactoryObject is requested
from the container, it creates a new instance of IncrediblyComplicatedObject. When set to true it will
create an instance once, and return this on every subsequent call. (At least, if the interface is properly
implemented :) ).

In order to use an IFactoryObject in your application, include it as an object in your application context:

<object class="com.myclasses.factories.IncrediblyComplicatedObjectFactory" id="incr

After that, requesting an instance of IncrediblyComplicatedObject is the same as requesting any other
ordinary object from the container:

var complicated:IncrediblyComplicatedObject = applicationContext.getObject("incredi

Finally, there is sometimes a need to ask a container for an actual IFactoryObject instance itself, not the
object it produces. This may be achieved by prepending the object id with '&' (sans quotes) when calling
the getObject method of the ObjectFactory (including ApplicationContext). So for a given IFactoryObject
with an id of myObject, invoking getObject("myObject") on the container will return the product of the
IFactoryObject, but invoking getObject("&myObject") will return the IFactoryObject instance itself.

Customizing configuration metadata with the


IObjectFactoryPostProcessor interface
The next extension point that we will look at is the
org.springextensions.actionscript.ioc.factory.config.IObjectFactoryPostProcessor. The semantics of this
interface are similar to the IObjectPostProcessor, with one major difference: IObjectFactoryPostProcessors
operate on the object configuration metadata; that is, the Spring Actionscript IoC container will allow
IObjectFactoryPostProcessors to read the configuration metadata and potentially change it before the
container has actually instantiated any other objects.

The interface is fairly simple as you can see:

public interface IObjectFactoryPostProcessor {

function postProcessObjectFactory(objectFactory:IConfigurableListableObjectFactory
}

53
The Inversion of
Control (IoC) container

In order to use an IObjectFactoryPostProcessor in your application, include the implementation as an


object in your application context:

<object class="com.myclasses.postprocessors.MyObjectFactoryPostProcessor" id="objec

Now after the application context has finished loading its configuration file, and before it starts
instantiating any objects every IObjectFactoryPostProcessor that was found in the configuration
will be invoked by calling its postProcessObjectFactory() method and passing the current
IConfigurableListableObjectFactory instance as the argument. The IObjectFactoryPostProcessor can then
use the IConfigurableObjectFactory, IListableObjectFactory and IConfigurableListableObjectFactory
interfaces to perform whatever postprocessing logic is necessary.

Note
Just as in the case of IObjectPostProcessors, you typically don't want to have
IObjectFactoryPostProcessors marked as being lazily-initialized. If they are marked as such, then
the Spring Actionscript container will never instantiate them, and thus they won't get a chance
to apply their custom logic.

Controlling collection order


Several collections (ObjectFactoryPostProcessors, ObjectPostProcessors, ClassScanners and
MetadataProcessors) available in the application context can be sorted into a prefered order using the
IOrdered interface. Let's have a look at it:

public interface IOrdered {

function get order():int;

function set order(value:int):void;

The actual order can be interpreted as prioritization, with the first object (with the lowest order value)
having the highest priority. When collections are sorted that contain objects that do not implement the
IOrdered interface first the IOrdered implementations will be sorted with the lowest order value first, after
that the remaining objects will be concatenated unordered. For sorting such a collection the static method
OrderedUtils.sortOrderedArray() may be used.

54
Part II. APIs and extensions
Other Spring Actionscript APIs and extensions for 3rd party frameworks
Chapter 3. Metadata annotations
handling
Introduction
Spring Actionscript offers an easy way to process actionscript metadata annotations. The main interface
of interest for this task is IMetadataProcessor.

Here's what it looks like up close:

public interface IMetadataProcessor {

function get metadataNames():Array;

function get processBeforeInitialization():Boolean;

function process(instance:Object, container:IMetaDataContainer, name:String, objec


}

The basic properties have already been implemented by the AbstractMetadataProcessor base class which
can be used for convenience.

Let's take a look at the various properties and methods and see what they do and mean.

• metadataNames - This is an Array of metadata names that will trigger the process() method of the
IMetadataProcessor implementation.

• processBeforeInitialization - When set to true the IMetadataProcessor instance will be able to process
the annotated instance before it has been initialized by the Spring Actionscript container.

• process - This method will contain the processing logic that is associated with the various names
specified by the metadataNames property.

The process() method will naturally be the most important aspect in any implementation of the
IMetadataProcessor interface. It receives three parameters:

• instance - This is the object instance that was encountered with the specified metadata name on its class
or its methods or properties.

• container - The IMetaDataContainer that is associated with the instance, this can be any of these
subclasses: Type, Method, Accessor, Constant, Variable.

• name - The metadata name that triggered the invocation of the process() method.

• objectName - The name of the object definition in the Spring Actionscript container.

To use the IMetadataProcessor in an application add the implementation as an object definition to the
application context configuration like this:

<object id="mvcEventsProcessor" class="org.springextensions.actionscript.core.mvc.M

After that the processor is ready to go, when used in combination with the autowiring stage processor (as
described in this section) it will process both objects created by the container and components that
were added to the stage.

56
Metadata annotations handling

Note
Credit where credit is due: This type of metadata handling was pioneered by the team, the Spring
Actionscript team both acknowledges and appreciates their work.

Controlling the order of IMetadataProcessors


The order in which IMetadataProcessors are executed is controlled by the IOrdered interface. See the
'Controlling collection order' section for more information on this interface.

57
Chapter 4. The Operation API
Introduction
One of the most prevalent actions in any Flash or Flex application is: Get stuff from the server back-end.
Be it calling a remote object, loading a sub-application, module or resource file, all of these actions have
one thing in common: They are asynchronous.

The Flex framework and Flash player seem to use different kinds of asynchronous patterns for different
kinds of retrieval. There's the responder method, the event based method (all be it with an optional
progress reporting mechanism), calls to a singleton that returns an IEventDispatcher instance or some other
interface, etc.

The Spring Actionscript Operation API aims to facilitate a common wrapper for these different patterns in
order to make using and combining them a little easier. The provided interfaces and base classes will give
a developer the opportunity to easily write his own logic. In addition to this, Spring Actionscript already
offers classes for the most common asynchronous tasks such as the loading of Flex modules, resource
modules and remote object calls.

Note
The Operation API is not an MVC or MVCS framework. The Spring Actionscript team believes
that a framework approach is too rigid, instead it offers a set of low-level classes and interfaces
that allows a developer to create a custom solution for each project/application he/she is working
on. No application is the same, therefore Spring Actionscript chose to offer building blocks
instead of a framework.

All the classes and interfaces described in this chapter can be found in the package.

Operations, commands, services and tasks


The Operation API, broadly speaking, has four concepts:

1. Operation: An asynchronous action.

2. Command: An action with deferred execution.

3. Service: A collection of related operations.

4. Task: A collection of commands that are executed using a control flow.

Operations
An operation represents any kind of asynchronous action and is described by the IOperation interface:

public interface IOperation extends IEventDispatcher {

function get result():*;

function get error():*;

function addCompleteListener(listener:Function, useCapture:Boolean = false, priori

58
The Operation API

function addErrorListener(listener:Function, useCapture:Boolean = false, priority:

function removeCompleteListener(listener:Function, useCapture:Boolean = false):voi

function removeErrorListener(listener:Function, useCapture:Boolean = false):void;

The most important properties of this interface are the result and error properties, these will be assigned
with the results of the asynchronous action. The names speak for themselves.

Note
An IOperation implementation will always execute its action immediately after creation, all
necessary parameters are therefore typically passed to the constructor of an implementation.

Long running operations


Operations that take long amounts of time to complete, such as downloading modules or other types of
assets benefit from being able to notify the user of their progress. Typically a progress bar could be display
this. For these types of operations there is the IProgressOperation interface, which is a simple extension
of IOperation:

public interface IProgressOperation extends IOperation {

function get progress():uint;

function get total():uint;

function addProgressListener(listener:Function, useCapture:Boolean = false, priori

function removeProgressListener(listener:Function, useCapture:Boolean = false):voi


}

Operation queues
In some cases a collection of IOperations need to be run at once, yet each individual
OperationEvent.COMPLETE event doesn't need to be listened for. All that is important is that all of the
IOperations are completed successfully. For this situation the OperationQueue class can help out. A simple
usage of this class might be like this:

var queue:OperationQueue = new OperationQueue();


queue.addCompleteListener(handleQueueComplete);
queue.addOperation(new FirstOperation());
queue.addOperation(new SecondOperation());
queue.addOperation(new ThirdOperation());
queue.addOperation(new FourthOperation());

And that's all, upon adding the operations the queue immediately starts running. So after all four operations
have completed the specified handleQueueComplete method will be invoked and the application can go
on about its business.

Common Spring Actionscript operations


Here is a list of all the IOperation implementations for common usage scenarios that Spring Actionscript
contains:

59
The Operation API

• LoadPropertiesOperation

• LoadPropertiesBatchOperation

• LoadStyleModuleOperation

• LoadURLOperation

• LoadModuleOperation

• NetConnectionOperation

• RemoteObjectOperation

• LoadResourceBundleOperation

• LoadResourceModuleOperation

• LoadURLStreamOperation

• HTTPServiceOperation

• WebServiceOperation

Commands
A command is any kind of action whose execution is deferred. Only after invoking the command's
execute() method will the action do its work. The basic ICommand interface is very modest:

public interface ICommand {

function execute():*;

This represents a synchronous command, so the logic that is executed by an implementation will be
available immediately after the call to the execute() method, and typically be returned in the execute()'s
result.

More interesting is the IAsyncCommand interface which is actually just a combination of the ICommand
and IOperation interfaces:

public interface IAsyncCommand extends ICommand, IOperation {

This interface allows a command to be constructed that will execute an asynchronous action. So contrary
to an IOperation instance an IAsyncCommand can be created, but its logic executed at a later moment.

Because the command is asynchronous the result property will be null directly after the execute() method
has been called, also the result of the execute() method will be either null or undefined. To retrieve the result
of the IAsyncCommand, add listeners for the OperationEvent.COMPLETE and OperationEvent.ERROR
events.

Composite commands
Just like IOperations its very well possible that a collection of ICommands or IAsyncCommands (or a
mixed collection of them) needs to be executed. For this scenario the CompositeCommand class is ideal.

60
The Operation API

It allows a list of ICommands to be executed in parallel or sequence. The CompositeCommand class is an


implementation of the ICompositeCommand interface:

public interface ICompositeCommand extends ICommand, IOperation {

function addCommand(command:ICommand):void;

function get numCommands():uint;

function get kind():ComposeiteCommandKind;


}

A simple example of the usage of a CompositeCommand instance would be like this:

var compositeCommand:CompositeCommand = new CompositeCommand(ComposeiteCommandKind.


compositeCommand.addCommand(new FirstCommand());
compositeCommand.addCommand(new SecondCommand());
compositeCommand.addCommand(new ThirdCommand());
compositeCommand.addCommand(new FourthCommand());
compositeCommand.addCompleteListener(handleCompositeCommandComplete);
compositeCommand.addErrorListener(handleCompositeCommandError);
compositeCommand.execute();

This will execute the FirstCommand instance, wait for it to complete, execute the SecondCommand
instance, wait for it to complete, etc.

If all commands complete successfully the specified handleCompositeCommandComplete method will


be invoked, if an error occurs the handleCompositeCommandError method is invoked instead.

Note
The failOnFault property determines whether the CompositeCommand instance should stop
executing its list of commands in the case of an error. Default this property is set to false. So all
commands will be executed no matter what their result is.

See the section 'the composite-command XML shortcut' to find out about custom XML configuration for
this class.

GenericOperationCommand
Having an ICommand implementation of each and every IOperation in an application isn't always practical,
therefore the GenericOperationCommand might help out a little. The GenericOperationCommand is
nothing more than a simple IAsyncCommand wrapper. All that a GenericOperationCommand needs is the
Class of an arbitrary IOperation and an optional list of constructor arguments. For example, here is how
the LoadModuleOperation would be wrapped:

var genericOperationCommand = new GenericOperationCommand(LoadModuleOperation, 'mod


genericOperationCommand.addCompleteHandler(operationCompleteHandler);
genericOperationCommand.execute();

GenericOperationCommand inside a CompositeCommand


Its not necessary to wrap an IOperation in a GenericOperationCommand when adding it to a
CompositeCommand. The CompositeCommand also has an addOperation() method which has this
signature:

61
The Operation API

function addOperation(operationClass:Class, ...constructorArgs):ICompositeCommand;

Which is basically the same as the constructor for a GenericOperationCommand, so adding a


LoadModuleOperation to a CompositeCommand instance would work like this:

compositeCommand.addOperation(LoadModuleOperation, 'module.swf');

The OperationHandler helper class


The OperationHandler is a helper class that generically handles IOperation events and either routes their
result or error data to a specified method or assigns them to a specified property on an object instance.

Below are some examples of its usage.

Assigning an operation result to an instance property

public class MyPresentationModel {

private var _operationHandler:OperationHandler

public var products:Array;

public function MyPresentationModel(){


_operationHandler = new OperationHandler(this.errorHandler);
}

public function getProducts():void {


var operation:IOperation = serviceImplementation.getProducts();
_operationHandler.handleOperation(operation,null,this,"products");
}

protected function errorHandler(error:):void {


//implementation omitted
}
}

Assigning an operation result to an instance property using an extra method

If the data returned from the IOperation needs some extra processing, specify an extra method for it like
in this example:

public class MyPresentationModel {

private var _operationHandler:OperationHandler

public var products:ArrayCollection;

public function MyPresentationModel(){


_operationHandler = new OperationHandler(this.errorHandler);
}

public function getProducts():void {


var operation:IOperation = serviceImplementation.getProducts();
_operationHandler.handleOperation(operation,convertArray,this,"products");
}

62
The Operation API

protected function convertArray(input:Array):ArrayCollection {


return new ArrayCollection(input);
}

protected function errorHandler(error:):void {


//implementation omitted
}
}

Services
It makes sense to encapsulate a number of operations in one interface. The easiest example would be the
CRUD operations for a specific object.

Let's imagine a user service whose interface looks like this:

public interface IUserService {

function createUser():IOperation;

function updateUser(user:User):IOperation;

function deleteUser(user:User):IOperation;

In a lot of cases the implementation for such a service will rely on a RemoteObject. For this situation Spring
Actionscript offers the base class RemoteObjectService. So the implementation for the IUserService could
inherit from this:

public class UserService extends RemoteObjectService implements IUserService {

public function UserService(remoteObject:RemoteObject) {


Assert.notNull(remoteObject,"remoteObject argument must not be null");
super(remoteObject);
}

public function createUser():IOperation {


return call('createUser');
}

public function updateUser(user:User):IOperation {


return call('updateUser',user);
}

public function deleteUser(user:User):IOperation {


return call('deleteUser',user);
}
}

This service could be injected into a presentation model, a command, a supervising presenter, etc. All
depending on the specific patterns used in an application.

Let's look at a command example:

63
The Operation API

public class CreateUserCommand extends AbstractOperation implements IAsyncCommand {

private var _userService:IUserService;


private var _applicationModel:IApplicationModel;

public function CreateUserCommand(userService:IUserService, applicationModel:IAppl


Assert.notNull(userService,"userService argument must not be null");
Assert.notNull(applicationModel,"applicationModel argument must not be null");
_userService = userService;
_applicationModel = applicationModel;
}

public function execute():* {


var operation:IOperation = _userService.createUser();
operation.addCompleteListener(handleComplete);
operation.addErrorListener(handleError);
}

protected function handleComplete(event:OperationEvent):void {


_applicationModel.users.addItem(event.result as User);
dispatchCompleteEvent(event.result);
}

protected function handleError(event:OperationEvent):void {


dispatchErrorEvent(event.error);
}

In this example the command receives a reference to an IUserService and IApplicationModel instance.
In this example we assume the IApplicationModel instance has a property called users of type
ArrayCollection. Once the IOperation that was received from the service completes it adds the result of
the IOperation (which is a User object) to the user collection in the application model.

Tasks
In order to support more complex execution of ICommand collections there is finally the ITask interface.
This interface describes an object that not only can execute collections of ICommands both in parallel and
in sequence, but also does this with basic control flow functionality.

First let's take a quick look and the ITask interface:

public interface ITask extends ICommand, IOperation {

function get context():Object;


function set context(value:Object):void;

function get parent():ITask;


function set parent(value:ITask):void;

function next(item:Object, ...constructorArgs):ITask;

function and(item:Object, ...constructorArgs):ITask;

64
The Operation API

function if_(condition:IConditionProvider=null, ifElseBlock:IIfElseBlock=null):IIf

function else_():IIfElseBlock;

function while_(condition:IConditionProvider=null, whileBlock:IWhileBlock=null):IW

function for_(count:uint, countProvider:ICountProvider=null, forBlock:IForBlock=nu

function exit():ITask;

function reset(doHardReset:Boolean = false):ITask;

function pause(duration:uint, pauseCommand:ICommand=null):ITask;

function end():ITask;
}

First thing that is apparent in this interface is that almost each method returns an ITask instance. This
actually implies that this is a so-called fluent interface. Meaning that method calls to a single instance of
an ITask can be chained. For instance, if we want to use a Task instance to execute a number of commands
in parallel we can write this:

var task:Task = new Task().and(new FirstCommand()).and(new SecondCommand()).and(new


task.addEventListener(TaskEvent.TASK_COMPLETE, handleTaskComplete);
task.execute();

This is basically the same as an ICompositeCommand set to CompositeCommandKind.PARALLEL, so


not that interesting. But the nice thing about a Task is the opportunity to mix the different types of
execution. So if we first want to execute a number of commands in parallel but after that a few in sequence,
we can use the same Task instance:

var task:Task = new Task().and(new FirstCommand()).and(new SecondCommand()).next(ne


task.addEventListener(TaskEvent.TASK_COMPLETE, handleTaskComplete);
task.execute();

This will first execute FirstCommand and SecondCommand in parallel and afterwards execute
ThirdCommand and FourthCommand in sequence.

The first argument for the next() and and() methods can be either an ICommand implementation, or a
Class that implements the IOperation interface along with an optional list of constructor arguments for the
IOperation instantiation. So this can also be a valid invocation:

new Task().and(LoadModuleOperation, 'module.swf');

Now let's have a look at some control flow elements, what if a certain command needs to be executed
more than once? We can use a for_() invocation for this:

var task:Task = new Task();

task.for_(10)
.next(new FirstCommand())
.end();

task.addEventListener(TaskEvent.TASK_COMPLETE, handleTaskComplete);
task.execute();

65
The Operation API

This will execute the FirstCommand 10 times. Now, it won't always be possible to know the exact number
of iterations at compile-time. Therefore its possible to pass an optional ICountProvider instance to the
for_() method. The ICountProvider interface is quite small:

public interface ICountProvider {


function getCount():uint;
}

Any implementations of this interface can perform their own kind of logic to determine the exact count,
this implementation can also be an IOperation so the logic for retrieving the count may be asynchronous,
internally the ForBlock will take care of this.

An ICommand may also be executed conditionally, for this use the if_() method and pass an
IConditionProvider to it:

var task:Task = new Task();

task.if_(new MyConditionProvider())
.next(new FirstCommand())
.end();

task.addEventListener(TaskEvent.TASK_COMPLETE, handleTaskComplete);
task.execute();

Now let's take a look at the IConditionProvider interface:

public interface IConditionProvider {


function getResult():Boolean;
}

The result of the getResult() method determines whether the commands inside the if block will be executed
or not. Again, an IConditionProvider implementation may also itself be an IOperation, and therefore have
its logic be executed in an asynchronous manner.

Of course, the if block may also have an else block:

var task:Task = new Task();

task.if_(new ConditionProvider())
.next(new FirstCommand())
.else_()
.next(new SecondCommand())
.end();

task.addEventListener(TaskEvent.TASK_COMPLETE, handleTaskComplete);
task.execute();

An IConditionProvider can also be used by a while block:

var task:Task = new Task();

task.while_(new MyConditionProvider())
.next(new FirstCommand())
.end();

task.addEventListener(TaskEvent.TASK_COMPLETE, handleTaskComplete);

66
The Operation API

task.execute();

In this case the FirstCommand will be executed for as long as the IConditionProvider.getResult() method
returns true.

In closing there are three last methods that an ITask implementation offers:

1. Exit(): stops the execution of the entire task.

2. Reset(): restarts the execution of the current task.

3. Pause(): pauses the execution of the current task for a specified period.

The task namespace handler


Configuring a task in Spring Actionscript XML is of course the final piece of functionality that Spring
Actionscript offers. There is a namespace handler to make task configuration a little easier. There's two
things that need to be added to the context and configuration.

First of all add the namespace to the configuration:

<?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:t="http://www.springactionscript.org/schema/task"
xsi:schemaLocation="
http://www.springactionscript.org/schema/objects http://www.springactionscript.or
http://www.springactionscript.org/schema/task http://www.springactionscript.org/s

<!-- further markup ommitted -->


</objects>

After that an instance of the TaskNamespaceHandler class needs to be added to the application context:

applicationContext.addNamespaceHandler(new TaskNamespaceHandler());

That's it, the application context is now ready to be able to parse task specific configuration XML.

Let's re-create the example where two commands are executed in parallel and two in sequence:

<t:task id="testTask" scope="prototype">


<t:and>
<object id="command1" scope="prototype" class="classes.commands.FirstCommand"/>
</t:and>
<t:and>
<object id="command2" scope="prototype" class="classes.commands.SecondCommand"/>
</t:and>
<t:next>
<object id="command3" scope="prototype" class="classes.commands.ThirdCommand"/>
</t:next>
<t:next>
<object id="command3" scope="prototype" class="classes.commands.FourthCommand"/>
</t:next>
</t:task>

Its also possible to declare the command objects outside of the task specific XML:

67
The Operation API

<object id="command1" scope="prototype" class="classes.commands.FirstCommand"/>


<object id="command2" scope="prototype" class="classes.commands.SecondCommand"/>
<object id="command3" scope="prototype" class="classes.commands.ThirdCommand"/>
<object id="command3" scope="prototype" class="classes.commands.FourthCommand"/>

<t:task id="testTask" scope="prototype">


<t:and command="command1"/>
<t:and command="command2"/>
<t:next command="command3"/>
<t:next command="command4"/>
</t:task>

A conditional execution could be configured like this:

<object id="command1" scope="prototype" class="classes.commands.FirstCommand"/>


<object id="command2" scope="prototype" class="classes.commands.SecondCommand"/>
<object id="myCondition" scope="prototype" class="classes.condition.MyConditionProv

<t:task id="testTask" scope="prototype">


<t:if condition="myCondition">
<t:next command="command1"/>
<t:else/>
<t:next command="command2"/>
</t:if>
</t:task>

A for loop would look like this:

<object id="command1" scope="prototype" class="classes.commands.FirstCommand"/>


<object id="command2" scope="prototype" class="classes.commands.SecondCommand"/>

<t:task id="testTask" scope="prototype">


<t:for count="10">
<t:next command="command1"/>
<t:next command="command2"/>
</t:for>
</t:task>

Or, when using an ICountProvider:

<object id="command1" scope="prototype" class="classes.commands.FirstCommand"/>


<object id="command2" scope="prototype" class="classes.commands.SecondCommand"/>
<object id="myCount" scope="prototype" class="classes.counts.MyCountProvider"/>

<t:task id="testTask" scope="prototype">


<t:for count-provider="myCount">
<t:next command="command1"/>
<t:next command="command2"/>
</t:for>
</t:task>

And finally, of course, the while loop:

<object id="command1" scope="prototype" class="classes.commands.FirstCommand"/>


<object id="command2" scope="prototype" class="classes.commands.SecondCommand"/>

68
The Operation API

<object id="myCondition" scope="prototype" class="classes.condition.MyConditionProv

<t:task id="testTask" scope="prototype">


<t:while condition="myCondition">
<t:next command="command1"/>
<t:next command="command2"/>
</t:while>
</t:task>

Common operation XML shortcuts


To add, for instance, a LoadModuleOperation to a task, this XML mark up would normally be needed:

<t:task id="testTask" scope="prototype">


<t:and>
<object class="org.springextensions.actionscript.core.command.GenericOperationCom
<constructor-arg value="org.springextensions.actionscript.module.LoadModuleOper
<constructor-arg value="modules/mymodule.swf"/>
</object>
</t:and>
//etc...
</t:task>

This is quite verbose so Spring Actionscript offers XML shortcuts for a number of common operations:

• LoadModuleOperation

• LoadPropertiesBatchOperation

• LoadPropertiesOperation

• LoadResourceModuleOperation

• LoadStyleModuleOperation

• LoadURLOperation

• LoadURLStreamOperation

Here's an example of how all these operations can be configured in XML for a task:

<t:task id="testTask" scope="prototype">


<t:next>
<t:load-module url="modules/mymodule.swf" application-domain="appDomainObjectName
</t:next>
<t:next>
<t:load-properties-batch locations="props/properties1.properties,props/properties
ignore-resource-not-found="true" prevent-cache="false"/>
</t:next>
<t:next>
<t:load-properties location="props/properties1.properties" prevent-cache="false"/
</t:next>
<t:next>
<t:load-resource-module url="resource.swf" update="false" application-domain="app
security-domain="secDomainObjectName"/>
</t:next>

69
The Operation API

<t:next>
<t:load-style-module url="styles.swf" update="false" application-domain="appDomai
security-domain="secDomainObjectName" flex-module-factory="moduleFactoryName"/>
</t:next>
<t:next>
<t:load-url url="someAsset.png" data-format="binary"/>
</t:next>
<t:next>
<t:load-url-stream url="someAsset.png"/>
</t:next>
</t:task>

The application domain attributes could be configured like this as well:

<t:load-resource-module url="resource.swf" update="false" application-domain="this.

This would assign the application domain that is associated with the application context that has consumed
this configuration. See this section: 'Injecting the application context using the 'this' reference' for more
information.

In that same vain the flex module factory for a LoadStyleModuleOperation could be configured like this:

<t:load-style-module url="styles.swf" update="false" application-domain="this.appli


flex-module-factory="this.ownerModule.moduleFactory"/>

The composite-command XML shortcut


A CompositeCommand can also be configured using a bit of custom XML, instead of writing this...

<object id="myCompositeCommand" class="org.springextensions.actionscript.core.comma


<property name="failOnFault" value="true"/>
<property name="kind">
<ref>
<util:constant static-field="org.springextensions.actionscript.core.command.C
</ref>
</property>
<method-invocation name="addCommand">
<arg>
<object id="myCommand1" class="..."/>
</arg>
</method-invocation>
<method-invocation name="addCommand">
<arg>
<object id="myCommand2" class="..."/>
</arg>
</method-invocation>
<!-- etc, etc -->
</object>

...this rather more abbreviated form is possible using the Task namespace handler:

<t:composite-command fail-on-fault="true" kind="parallel">


<object id="myCommand1" class="..."/>
<object id="myCommand2" class="..."/>
</t:composite-command>

70
Chapter 5. The EventBus
Introduction
In a de-coupled environment, its not always easy to let various components communicate with each other.
In order to make this task slightly easier Spring Actionscript includes the EventBus class.

The EventBus is a final class with only static methods. In Actionscript it is not possible to define an
interface with static methods. In order to still provide an interface there does exist the IEventBus. This
interface is implemented by the EventBusFacade, which re-routes all of its methods to their EventBus
equivalent. This way it is easier to mock up an IEventBus for unit testing purposes.

EventBus listening
There are a number of different ways to subscribe to events that are dispatched through the EventBus:

The first is to listen to all events that are dispatched through the EventBus. This is possible through
the EventBus.addListener method. This method expects an IEventBusListener as an argument. The
IEventBusListener looks like this:

public interface IEventBusListener {

function onEvent(event:Event):void;

Every event dispatched by the EventBus will be passed into the onEvent method.

The second method is to only listen for events of a specific type. Use the EventBus.addEventListener for
this task. The addEventListener method expects two arguments, the first is a string representing the event
type, and the second is a Function instance which will be invoked with every event of the specified type.

Instead of a Function it is also possible to supply a proxy instead. This is what the addEventListenerProxy
method is for. Instead of a Function this expects a instance. The class is part of the package.

The last option is to add a listener for events of a certain class. To get this to happen use the
addEventClassListener or addEventClassListenerProxy methods. The same arguments apply to these as
for their addEventListener and addEventListenerProxy neighbours, except they expect a Class instance
instead of a type.

All these methods naturally have a removal counterpart: removeListener, removeEventListener,


removeEventListenerProxy, removeEventClassListener and removeEventClassListenerProxy.

To clear all types of registered eventlisteners at once simply call the removeAll() method.

EventBus dispatching
This is the easiest part, to dispatch an event through the EventBus invoke either the dispatchEvent or
dispatch methods. The former expects an Event instance while the latter expects a string that indicates a
certain type of Event. This event will be created by this method and subsequently dispatched. For example:

EventBus.dispatchEvent(new MyCustomEvent("myCustomEventType"));

71
The EventBus

or

EventBus.dispatch("myCustomEventType");

EventBus event handling using metadata annotations


To prevent a lot of boilerplate code consisting of long lists of addEventListener* calls, Spring Actionscript
includes an alternative way to define event handlers for events that are dispatched through the EventBus.

Instead of adding specific listeners functions through the addEventListener calls simply add a bit of
metadata to the particular method:

[EventHandler]
protected function saveUserHandler(event:Event):void {
//implementation ommitted...
}

This is the most basic way of annotating a method and immediately implies certain assumptions. In this
case it is assumed that the saveUser method will handle an event of the type "saveUser". Another valid
method name for this handler could also be:

[EventHandler]
protected function saveUser(event:Event):void {
//implementation ommitted...
}

If, for some reason, this naming convention is not desired then add the name of the type of the specific
event to the metadata:

[EventHandler(name="saveUser")]
protected function saveTheUserNow(event:Event):void {
//implementation ommitted...
}

By default, an event handler function is expected to have a single argument of type Event (or any subclass).
It is however possible to let Spring Actionscript match the properties of the specified event with the
arguments of the event handler. For instance, if the event passed to the saveUser event is not an ordinary
event, but a subclass called SaveUserEvent with a property that is called "user" of the type "User". In this
case an event handler with the following signature will work just a well:

[EventHandler]
protected function saveUser(user:User):void {
//implementation ommitted...
}

The property/argument matching is done by type, so this will fail in the case where an event has multiple
properties of the same kind. If the SaveUserEvent should have two user properties, called userA or userB
for example, the matching will fail. In that case it is possible to define the properties by name directly
in the metadata:

[EventHandler(properties="userA,userB")]
protected function saveUser(userA:User, userB:User):void {
//implementation ommitted...
}

To annotate a handler for a certain event Class, define the fully qualified class name like this:

72
The EventBus

[EventHandler(clazz="com.classes.events.UserEvent")]
protected function saveTheUserNow(event:UserEvent):void {
//implementation ommitted...
}

To enable the processing of these kinds of annotations it is necessary to add an instance of the
EventHandlerMetaDataPostProcessor to the application context. The easiest way to do so is to add this
bit of XML to the configuration:

<object id="eventhandlerProcessor" class="org.springextensions.actionscript.ioc.fac

This will automatically register the processor with the application context.

Note
Do not forget to add the EventHandler metadata to the compiler arguments: -keep-as3-metadata
+=EventHandler. Failing to do so will prevent the EventHandlerMetaDataPostProcessor to do
its work.

Note
Credit where credit is due: The [EventHandler] handling is similar to the [Mediate] metadata
as first introduced by in the , the Spring Actionscript team both acknowledges and appreciates
his work.

Routing other events through the EventBus


On the other side of the spectrum there is event dispatching and a way to avoid having to call
EventBus.dispatch(someEvent) a zillion times. For this particular goal there is the [RouteEvents] metadata
which can be handled by the RouteEventsMetaDataPostProcessor. Let's take a look at simple example,
imagine a class that is able to dispatch a number of events:

[Event(name="eventName1",type="...")]
[Event(name="eventName2",type="...")]
[Event(name="eventName3",type="...")]
public class MyClass {
//implementation omitted..
}

To let Spring Actionscript catch all these events, and redispatch them through the EventBus, all that is
necessary is the addition of the [RouteEvents] metadata:

[RouteEvents]
[Event(name="eventName1",type="...")]
[Event(name="eventName2",type="...")]
[Event(name="eventName3",type="...")]
public class MyClass {
//implementation omitted...
}

If not all events need to be re-routed then use the 'events' argument of the [RouteEvents] metadata:

[RouteEvents(events="eventName1,eventName2")]
[Event(name="eventName1",type="...")]
[Event(name="eventName2",type="...")]

73
The EventBus

[Event(name="eventName3",type="...")]
public class MyClass {
//implementation omitted...
}

And that's all there is to it, now to enable this functionality add this object definition to the XML
configuration:

<object id="routeEventsProcessor" class="org.springextensions.actionscript.ioc.fact

This will automatically register the processor with the application context.

Note
Do not forget to add the RouteEvents metadata to the compiler arguments: -keep-as3-metadata
+=RouteEvents. Failing to do so will prevent the RouteEventsMetaDataPostProcessor to do its
work.

The combination of the [RouteEvents] and [EventHandler] enables a developer to leverage the EventBus
without directly depending on it.

Metadata driven MVC micro-framework


Leveraging the above described classes and techniques Spring Actionscript offers a small metadata driven
MVC micro-framework. These are the key components that this framework provides:

• Fully metadata driven

• Works with regular Flash events (flash.events.Event)

• No need to implement Spring Actionscript interfaces or inherit from base classes

• Plays nice in multi-module environments

The framework uses metadata tags in event and command classes to define mappings between them and
the application context as a class factory for the commands.

Getting started
First add this object definition to the application context XML configuration:

<object id="mvcFactory" class="org.springextensions.actionscript.core.mvc.MVCContro

The MVCControllerObjectFactoryPostProcessor is an IObjectFactoryPostProcessor implementation that


takes care of all the metadata processing and event/command mapping.

This factory postprocessor first checks for the existence of an IMVCEventObjectPostProcessor


implementation in the application context, when none is found it creates an instance of the
MVCRouteEventsMetaDataProcessor class and adds it to the application context singleton cache. This
allows for the events postprocessor to be overridden by another implementation.

After that the factory postprocessor checks if an IController implementation exists in the application
context, of not a Controller instance is created and added to the context so, if necessary, the IController
instance can be overridden again.

This takes care of the preparatory work, now all that remains is defining the event/command mappings.

74
The EventBus

Annotating classes that dispatch MVC events


Annotating components and classes that dispatch events that need to be mapped to a command is almost the
same as annotating them for dispatch through the EventBus (the EventBus is used by this MVC framework
as the main communication pipeline). So, let's have a simple example:

[RouteMVCEvents]
[Event(name="someEventType","flash.events.Event")]
public class SomeClassThatDispatchesMVCEvents {
//implementation ommitted...
}

This means that [RouteEvents] and [RouteMVCEvents] metadata can be combined. (A class could even
be annotated with both types of metadata.)

This is all that is necessary for the event side of things of the MVC functionality.

Annotating classes that act as MVC commands


To define a command that is to be triggered by the aforementioned event can be annotated in its simplest
form like this:

[Command(eventType="someEventType")]
public class CommandClass {
function execute():void {
//implementation ommitted...
}
//further implementation ommitted...
}

When the command is triggered by a certain event Class, define the class like this:

[Command(eventClass="com.events.CustomEvent")]
public class CommandClass {
function execute():void {
//implementation ommitted...
}
//further implementation ommitted...
}

The command class does not need to implement any kind of interfaces or inherit from any base classes.
By default the MVC framework will assume that a method called execute needs to be invoked. When a
different method name is needed this can be defined in the metadata tag:

[Command(eventType="someEventType",executeMethod="process")]
public class CommandClass {
function process():void {
//implementation ommitted...
}
//further implementation ommitted...
}

When the execution method needs to receive a reference to the event instance it will be automatically
mapped:

[Command(eventType="someEventType",executeMethod="process")]

75
The EventBus

public class CommandClass {


function process(event:Event):void {
//implementation ommitted...
}
//further implementation ommitted...
}

Properties on the event can be automatically mapped to the method arguments as well. Imagine for instance
this event class:

public class CustomEvent extends flash.events.Event {


public static const EVENT_ID:String = "someEventType";

public var user:User;


//further implementation ommitted...

If the command class has this definition, the property will be mapped automatically:

[Command(eventType="someEventType",executeMethod="process")]
public class CommandClass {
function process(user:User):void {
//implementation ommitted...
}
//further implementation ommitted...
}

The event properties can also be mapped to properties on the command:

[Command(eventType="someEventType",executeMethod="process")]
public class CommandClass {

public var user:User;

function process():void {
//implementation ommitted...
}
//further implementation ommitted...
}

The mapped event properties can also be explicitly named:

[Command(eventType="someEventType",executeMethod="process",properties="userA,userB"
public class CommandClass {

function process(userA:User, userB:User):void {


//implementation ommitted...
}
//further implementation ommitted...
}

Now all that is left is to add object definitions for each command that is used to the application context
XML configuration:

<object id="myCommand" class="com.classes.commands.CommandClass"/>

76
The EventBus

Or, alternatively, every command class can be annotated with the [Component] metadata and thus will be
picked up by the class scanning system:

[Component]
[Command(eventType="someEventType",executeMethod="process")]
public class CommandClass {
}

For further information on the class scanning system see section 'The Component scanner and class
scanning system'

Note
The application context can now be used as the main command classfactory, leveraging all of its
rich DI functionality. Services, models and other dependencies can be easily defined and injected.

77
Chapter 6. The Component scanner
and class scanning system
Introduction
Besides XML and MXML, it is possible to define object definitions through metadata annotations. This
is done using a system called component scanning.

What this does is, at application context startup, the system will scan all the classes that are defined in the
currently loaded SWF, examine them to determine whether they have been annotated with [Component]
metadata, and if so, create an ObjectDefinition based on the metadata arguments and register it with the
application context.

To use the below explained functionality, add these elements to the XML configuration:

<objects xmlns="http://www.springactionscript.org/schema/objects"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springactionscript.org/schema/context"
xsi:schemaLocation="
http://www.springactionscript.org/schema/objects http://www.springactionscript.org
http://www.springactionscript.org/schema/context http://www.springactionscript.org

<context:metadata-config/>
<context:component-scan/>

</objects>

or add it programmatically like this:

flexXMLApplicationContext.addObjectFactoryPostProcessor(new ClassScannerObjectFacto

Note
For now this functionality will only work with the FlexXMLApplicationContext since it makes
use of the SystemManager, at a later date we will try and implement this as well for pure
actionscript projects.

Note
Don't forget to add these compiler arguments to your project to be able to
make use of the annotations as described in this chapter: -keep-as3-metadata
+=Component,Property,Invoke,Constructor

[Component] metadata explained


Here is a simple example of a class that is annotated with [Component] metadata:

[Component]
public class AnnotatedComponent {

78
The Component scanner
and class scanning system

public function AnnotatedComponent() {


super();
}
}

This will register an object definition with a generated id for the AnnotatedComponent class. The XML
equivalent of this would be:

<object class="com.class.AnnotatedComponent" id="scannedComponent#1"/>

This in itself is not very useful yet, but here is how you can set different ObjectDefinition properties using
metadata arguments:

[Component(id="myComponent",scope="prototype",factoryMethod="getInstance")]
public class AnnotatedComponent {

public function AnnotatedComponent() {


super();
}

public static function getInstance():AnnotatedComponent {


//...implementation omitted
}
}

The XML equivalent for the above would be:

<object class="com.class.AnnotatedComponent" id="myComponent" scope="singleton"/>

Here is a list of all the metadata arguments that are available:

• [Component(id="componentId")]

• [Component(scope="singleton/prototype")]

• [Component(lazyInit="true/false")]

• [Component(factoryMethod="methodName")]

• [Component(factoryObjectName="objectName")]

• [Component(initMethod="methodName")]

• [Component(destroyMethod="methodName")]

• [Component(primary="true/false")]

• [Component(autowireCandidate="true/false")]

• [Component(dependencyCheck="none/simple/objects/all")]

• [Component(dependsOn="comma,delimited,list,of,object,names")]

• [Component(autowire="no,byName,byType,constructor,autodetect")]

• [Component(skipMetaData="true/false")]

• [Component(skipPostProcessors="true/false")]

79
The Component scanner
and class scanning system

Injecting constructor arguments


Since it is not possible to annotate actionscript constructors with metadata its constructor arguments will
need to be defined at class level, like so:

[Constructor(args="ref=objectName1")]
[Component(id="myComponent",scope="prototype")]
public class AnnotatedComponent {

public function AnnotatedComponent(obj:Object) {


super();
}

Its XML equivalent would be written like this:

<object id="myComponent" scope="prototype">


<constructor-arg ref="objectName1"/>
</object>

If the [Constructor] annotation is ommitted Spring Actionscript will try to resolve any available
constructor arguments through reflection in the same way that the 'constructor' autowiring logic is
performed. See the section 'Autowiring collaborators' for more info.

Injecting properties
Next up is how to inject property values, annotate property declarations as follows to achieve this:

[Component(id="myComponent",scope="prototype")]
public class AnnotatedComponent {

public function AnnotatedComponent() {


super();
}

[Property(ref="someObjectNameOfMyType")]
public var someProperty():MyType;

[Property(value="${propertyName}")]
public var someOtherProperty():String;

The '${propertyName}' value means that this placeholder will be replaced by a 'real' property value once
the ObjectDefinition is registered in the application context. The above annotations would look as follows
when configured in XML.

<object id="myComponent" scope="prototype">


<property name="someProperty" ref="someObjectNameOfMyType"/>
<property name="someOtherProperty" value="${propertyName}"/>
</object>

The same results can also be achieved by using these annotations:

80
The Component scanner
and class scanning system

[Component(id="myComponent",scope="prototype")]
public class AnnotatedComponent {

public function AnnotatedComponent() {


super();
}

[Autowired(name="someObjectNameOfMyType")]
public var someProperty():MyType;

[Autowired(externalProperty="propertyName")]
public var someOtherProperty():String;

There is however a subtle difference between these two techniques. In the first case, the [Property] case,
the property injection will be defined as a property on the object definition. Therefore it is possible that this
definition will be processed by other IObjectFactoryPostProcessor implementations (and thus the property
might be processed too) later in the application context bootstrap. In the second case, the [Autowired]
case, the injections will be resolved at runtime, at the moment that the context instantiates the object.

Both cases lead to the same result, but keep these small differences in mind when choosing which
annotation to use.

Method invocations
Lastly there are, of course, the method invocations. Annotating a method declaration as follows will add
a MethodInvocation to the generated ObjectDefinition:

[Component(id="myComponent",scope="prototype")]
public class AnnotatedComponent {

public function AnnotatedComponent() {


super();
}

[Invoke]
public var someFunction():void;

Of which the XML equivalent would look as below:

<object id="myComponent" scope="prototype">


<method-invocation name="someFunction"/>
</object>

If the method expects arguments they can be defined like this:

[Component(id="myComponent",scope="prototype")]
public class AnnotatedComponent {

public function AnnotatedComponent() {


super();
}

81
The Component scanner
and class scanning system

[Invoke(args="ref=someObjectNameOfMyType, value=10")]
public var someFunction(arg1:SomeType, arg2:uint):void;

And of course, its XML mirror:

<object id="myComponent" scope="prototype">


<method-invocation name="someFunction">
<arg ref="someObjectNameOfMyType"/>
<arg value="10"/>
</method-invocation>
</object>

Extending the class scanning system


The component scanner is part of the more generic class scanning system. It is quite easy to extend this
with custom scanners, in this section it will be explained how.

The IClassScanner interface


The ClassScannerObjectFactoryPostProcessor factory postprocessor mentioned in the introduction of this
chapter will query its associated application context for the existence of any implementations.

This interface looks like this:

public interface IClassScanner {

function scan(className:String):void;

function get metaDataNames():Array;


}

The metadataNames property determines which class level metadata annotations will trigger the
implementation. Once the ClassScannerObjectFactoryPostProcessor encounters a class that is annotated
with any of this metadata, its fully qualified class name will be passed to the method.

Let's imagine an that is interested in classes that are annotated with [Service] metadata, an implementation
could inherit from the provided base class like this:

public class ServiceClassScanner extends AbstractClassScanner {

public static const SERVICE_METADATA:String = "Service";

public function ServiceClassScanner() {


super([SERVICE_METADATA]);
}

function scan(className:String):void {
var type:Type = Type.forName(className);
//... further implementation ommitted
}

82
The Component scanner
and class scanning system

To register this implementation with the ClassScannerObjectFactoryPostProcessor add this bit of XML
configuration:

<object id="serviceScanner" class="com.classes.ServiceClassScanner"/>

<object id="classScanObjectFactoryPostProcessor"
class="org.springextensions.actionscript.context.metadata.ClassScannerObjectFac
<method-invocation name="addScanner">
<arg ref="serviceScanner"/>
</method-invocation>
</object>

Or add it programmatically like this:

var factory:ClassScannerObjectFactoryPostProcessor = new ClassScannerObjectFactoryP


factory.addScanner(new ServiceClassScanner());
flexXMLApplicationContext.addObjectFactoryPostProcessor(factory);

Note
Be careful, when defining class scanners in XML, not to let them be injected with any other
instances defined in the configuration. The ClassScannerObjectFactoryPostProcessor runs before
the application context has finished its bootstrap, so therefore cannot be used for IoC at this stage.

Controlling the order in which class scanners are


executed
The order in which a collection of IClassScanner implementations is executed can be controlled by having
them implement the IOrdered interface. See the 'Controlling collection order' section for more information
on this interface.

83
Chapter 7. Testing
Introduction
Testing is a fundamental part of software development.

Integration Testing
Overview
It is important to be able to perform some integration testing without requiring deployment of your
application or connecting to other enterprise infrastructure. This will enable you to test things such as:

• The correct wiring of your Spring IOC container contexts.

The Spring ActionScript Framework provides first class support for integration testing in the form of
classes that are packaged in the spring-actionscript-test.swc library. In this library you
will find the org.springextensisons.actionscript.test package which contain valuable
classes for integration testing using a Spring container, while at the same time not being reliant on a
deployment environment. Such tests will be slower to run than unit tests, but much faster to run than the
equivalent remote tests relying on deployment.

Spring ActionScript offers support for unit and integration testing in the form the Spring ActionScript
TestContext Framework, which is agnostic to the actual testing framework in use, thus allowing
instrumentation of tests in various environments. Note that the Spring ActionScript TestContext
Framework currently only supports FlexUnit 4.

Common Goals
The Spring ActionScript integration testing support framework has several goals, including:

• Spring IoC Container caching between test execution.

• Dependency Injection of test fixture instances.

• Spring-specific support classes that are really useful when writing integration tests.

The following sections outline each of these goals and provide direct link to information specific to the
particular support framework.

Context management and caching


The Spring integration testing support framework provide consistent loading of Spring
IApplicationContexts and caching of those context. Support for the caching of loaded contexts is
important, because if you are working on a large project, startup time may become an issue - not because of
the overhead of Spring itself, but because the objects instantiated by the Spring container will themselves
take time to instantiate.

Test classes will generally provide an array containing the resource locations of XML configuration
metadata - typically on the deploy path - used to configure the application. This will be the same, or nearly
the same, as the list of configuration locations specified in deployment configuration.

84
Testing

By default, once loaded, the configured IApplicationContext will be reused for each test. Thus
the setup cost will be incurred only once (per test fixture), and subsequent test execution will be much
faster. In the unlikely cases that a test may 'dirty' the application context, require reloading - for example,
by changing an object definition or the state of an application object - Spring's testing support provides
mechanisms to cause the test fixture to reload the configurations and rebuild the application context before
executing the next test.

Context management and caching with:

• The TestContext Framework

Dependency Injection of test fixtures


When the Spring integration testing support framework loads your application context, it can optionally
configure instances of your test classes via Dependency Injection. This provides a convenient mechanism
for setting up test fixtures using pre-configured objects from your application context. A strong benefit
here is that you can reuse application context across various testing scenarios (e.g., for configuring Spring-
managed object graphs, DataSources, etc.), this avoiding the need to duplicate complex test fixture set
up for individual test cases.

Dependency Injection of test fixtures with:

• The TestContext Framework

Integration testing support classes


The Spring integration testing support framework provides several abstract support classes that can
simplify writing integration tests. These base test classes provide well defined hooks into the testing
framework as well as convenient instance variable and methods, allowing access to such things as:

• The IApplicationContext: useful for performing explicit object lookups or testing the state of
the context as a whole.

Often you will provide an application-wide superclass for integration tests that provides further useful
instance variables used in many tests.

Support classes for:

• The TestContext Framework

Common Metadata
The Spring ActionScript Framework provides a common set of Spring-specific metadata that you can use
in your testing.

• [DirtiesContext]

The presence of this metadata on a test method indicates the underlying Spring container is 'dirtied'
during the execution of the test method, and thus must be rebuilt after the test method finishes execution
(regardless of whether the test passed or not).

[DirtiesContext]
public function testProcessWhichDirtiesAppCtx():void {
// some logic that results in the Spring container being dirtied
}

Metadata support for:

85
Testing

• The TestContext Framework: supports all of the common metadata listed above
while providing additional TestContext-specific (e.g., [ContextConfiguration],
TestExecutionListeners, etc.). Note, however, that some metadata are only supported when
used in conjunction with FlexUnit (e.g., with the SpringFlexUnit4ClassRunner). Refer to the
documentation in the TestContext Framework section for further details.

Spring ActionScript TestContext Framework


The Spring TestContext Framework (located in the
org.springextensions.actionscript.test.context package) provides generic,
metadata driven unit and integration testing support thia is agnostic of the testing framework in use. The
TestContext framework also places a great deal of importance on convention over configuration with
reasonable defaults that can overridden via metadata-based configuration.

In addition to generic testing infrastructure, the TestContext framework provides explicit support for
FlexUnit 4 in the form abstract support classes. For FlexUnit 4, the framework provides a custom
IRunner which allows one to write test classes that are not required to extend a particular class hierarchy.

The following section provides and overview of the internals of the TestContext framework. If you are
only interested in using the framework and not necessarily interested in extending it with your own custom
listeners, feel free to skip ahead to the configuration (context management, dependency injection), support
classes, and metadata support sections.

Key abstractions
The core of the framework consists of the TestContext and TestContextManager classes and
the ITestExecutionListener interface. A TestContextManager is created on a per-test basis.
The TestContextManager in turn manages a TestContext, which is responsible for holding
the context of the current test. The TestContextManager is also responsible for updating the
state of the TestContext as the test progresses and delegating to ITestExecutionListeners,
which instrument the actual test execution (e.g., providing dependency injection, dirtying context, etc.).
Consult the ASDoc and the Spring ActionScript test suite for further information and example of various
configurations.

• TestContext: encapsulate the context in which a text is executed, agnostic of the actual testing
framework in use.

• TestContextManager: the main entry point into the Spring ActionScript TestContext Framework,
which is responsible for managing a single TestContext and signaling event to all registered
ITestExecutionListeners at well defined test execution points: test instance preparation, prior
to any before methods of a particular testing framework, and after and after methods of a particular
testing framework.

• ITestExecutionListener: defines a listener API for reacting to test execution events published
by the TestContextManager with which the listener is registered.

Spring provides two ITestExecutionListener implementations which are


configured by default. (via the [TestExecutionListeners] metadata):
DependencyInjectionTestExecutionListener and
DirtiesContextTestExecutionListener, which provide support for dependency injection of
the test instance and handling of the [DirtiesContext] metadata, respectively.

Context management and caching


Each TestContext provides context management and caching support for the test instance for
which it is responsible. Test instances do not automatically receive access to the configured

86
Testing

IApplicationContext; however, if a test class implements the IApplicationContextAware


interface, a reference to the IApplicationContext will be supplied to the test instance
(provided the DependencyInjectionTestExecutionListener has been configured, which
is the default). Note that AbstractFlexUnit4SpringContextTests already implements
IApplicationContextAware and therefor provides this functionality out-of-the-box.

Configuration is achieved merely by declaring the [ContextConfiguration] metadata at the class


level. If your test class does not explicitly declare an application context resource locations, the
configured IContextLoader will determine how and whether or not to load a context from default
set of locations. If your class is named com.example.MyTest, GenericXMLContextLoader will
load your application context from "/com/example/MyTest-context.xml".

package com.example {

[RunWith("org.springextensions.actionscript.test.context.flexunit4.SpringFlexUnit4C
// IApplicationContext will be loaded from "/com/example/MyTest-context.xml"
[ContextConfiguration]
public class MyTest {
// class body...
}
}

If the default location does not suit your needs, you are free to explicitly configure the locations
attribute of [ContextConfiguration] (see code listing below) with a comma delimited list of the
resource locations of XML configuration metadata (assuming an XML-capable IContextLoader has
been configured) used to configure the application. This will be the same, or nearly the same, as the list
of configuration locations specified in deployment configuration. As an alternative you may choose to
implement and configure your own custom IContextLoader.

package com.example {

[RunWith("org.springextensions.actionscript.test.context.flexunit4.SpringFlexUnit4C
// IApplicationContext will be loaded from "/applicationContext.xml" and "/applicat
// in the root of the deploy directory
[ContextConfiguration(locations="/applicationContext.xml,/applicationContext-test.x
public class MyTest {
// class body...
}
}

[ContextConfiguration] also supports a boolean inheritLocations key that denotes


whether or not resource locations from superclasses should be inherited. The default value is true,
which means that an annotated class will inherit the resource locations defined by an annotated superclass.
Specifically, the resource locations for an annotated class will be appended to the list of resource
locations defined by an annotated superclass. In the following example, the IApplicationContext
for ExtendedTest will be loaded from "/base-context.xml" and "/extended-context.xml", in that order.
Objects defined in "/extended-context.xml" may therefore override those defined in "/base-context.xml".

[RunWith("org.springextensions.actionscript.test.context.flexunit4.SpringFlexUnit4C
// IApplicationContext will be loaded from "/base-context.xml" in the root of the d
[ContextConfiguration(locations="/base-context.xml")]
public class BaseTest {
// class body...
}

87
Testing

// IApplicationContext will be loaded from "/base-context.xml" and "/extended-conte


// in the root of the deploy directory
[ContextConfiguration(locations="/extended-context.xml")]
public class ExtendedTest extends BaseTest {
// class body...
}

If inheritLocations is set to false, the resource locations for the annotated class will shadow and
effectively replace and resource locations defined by a superclass.

By default, once loaded, the configured IApplicationContext will be reused for each test. Thus
the setup cost will be incurred only once (per test fixture), and subsequent test execution will be much
faster. In the unlikely case that a test may dirty the application context, requiring reloading - for example,
by changing an object definition or the state of an application object - you may annotate your test
method with [DirtiesContext] (assuming DirtiesContextTestExecutionListener has
been configured, which is the default) to cause the test fixture to reload the configurations and rebuild the
application context before executing the next test.

Dependency Injection of test fixtures


When you configure the DependencyInjectionTestExecutionListener - which is
configured by default - via the [TestExecutionListeners] metadata, the dependencies of
your test instances will be injected from objects in the application context you configured via
[ContextConfiguration] by Setter Injection, Field Injection, or both, depending on which
annotations you choose whether you place them on setter methods or fields.

Tip
The TestContext framework does not instrument the manner in which a test instance is
instantiated. Thus the use of [Autowired] for constructors has no effect for test classes.

Alternatively, if your test class implements IApplicationContextAware, you can directly access
the IApplicationContext supplied to your test and perform an explicit lookup using (for example)
a call to applicationContext.getObject("property").

If you don't want dependency injection applied to your test instances, simply don't annotate any
fields or setter methods with [Autowired]. Alternatively, you can disable dependency injection
altogether by explicitly configuring your class with [TestExecutionListeners] and omitting
DependencyInjectionTestExecutionListener from the list of listeners.

TestContext support classes


FlexUnit 4 support classes

The org.springextensions.actionscript.test.context.flexunit4 package


provides support classes for FlexUnit 4 based test classes.

• AbstractFlexUnit4SpringContextTests:

Abstract base test class that integrates the Spring TestContext Framework with explicit
IApplicationContext testing support in a FlexUnit 4 environment. When you extend
AbstractFlexUnit4SpringContextTests you will have access to the following public
instance variables:

• applicationContext: use this to perform explicit object lookups or to test the state of the
context as a whole.

88
Testing

Custom Flex Unit 4 Runner

The Spring TestContext Framework offers full integration with FlexUnit


4 via a custom runner. By annotating test classes with
[RunWith("org.springextensions.actionscript.test.context.flexunit4.SpringFlexUnit4C
developers can implement standard FlexUnit 4 unit and integration tests and simultaneously reap the
benefits of the TestContext framework such as support for loading application contexts, dependency
injection of test instances, etc. The following code listing displays the minimal requirement for configuring
a test class to run with the custom Spring Runner. Note: that [TestExecutionListeners] has been
configured with an empty list in order to disable default listeners, which would otherwise require that an
IApplicationContext be configured via [ContextConfiguration].

[RunWith("org.springextensions.actionscript.test.context.flexunit4.SpringFlexUnit4C
[TestExecutionListeners("")]
public class SimpleTest {

[Test]
public function testMethod():void {
// execute test logic...
}
}

TestContext framework annotation support


The Spring TestContext Framework supports all metadata as outlined in the common metadata section.
The following metadata, however, are only supported when used in conjunction with FlexUnit (e.g., with
the SpringFlexUnit4ClassRunner or the FlexUnit 4 support classes.

• Not Yet Implemented

The following non-test-specific annotations are supported by the Spring TestContext Framework with their
standard semantics.

• [Autowired]

• [Required]

The following list includes all annotations specific to the Spring TestContext Framework. Refer to the
respective ASDoc for further information, including default key values.

• [ContextConfiguration]

Defines class-level metadata that is used to determine how to load and configure an
IApplicationContext. Specifically, [ContextConfiguration] defines the application
context resource locations to load as well as the IContextLoader strategy to use for loading
the context.

[ContextConfiguration(locations="example/test-context.xml", loader="com.example.C
public class CustomConfiguredApplicationContextTests {
// class body...
}

Note: [ContextConfiguration] provides support for inherited resource locations by default. See
the Context management and caching section and ASDoc for an example and further details.

• [TestExecutionListeners]

89
Testing

Defines class-level metadata for configuring which ITestExecutionListeners should be


registered with a TestContextManager. Typically, [TestExecutionListeners] will be
used in conjunction with [ContextConfiguration].

[ContextConfiguration]
[TestExecutionListeners("CustomTestExecutionListener,AnotherTestExecutionListener
public class CustomTestExecutionListenerTests {
// class body...
}

Note: [TestExecutionListeners] provides support for inherited listeners by default. See the
ASDoc for an example and further details.

90
Chapter 8. Spring Actionscript
extensions
Introduction
In this section we describe several extensions of Spring Actionscript that will make the integration with
other frameworks a little easier.

Cairngorm 2
Spring Actionscript offers several extensions to the Cairngorm 2 micro-architecture that will make it easier
to configure the various objects by the Spring Actionscript IoC container. And some of them will just
make life a little easier when working with Cairngorm. What follows is a description of how to setup a
configuration file that will allow you to manage the Cairngorm framework externally.

Note
As you can see, we refer in this section to Cairngorm 2, the micro-architecture. A while ago
was released, which isn't a framework anymore but a set of guidelines, best practices and
accompanying tools.

The ModelLocator
One of the main criticisms on Cairngorm you'll read on the internet is its heavy use of the singleton pattern.
To obtain a reference to your model instance you need to call the static ApplicationModel.getInstance()
method every time you need one. This tightly couples your code to a specific implementation of your
model, which in a world of 'High Cohesion and Loose Coupling' is somewhat of a sin.

To circumvent this problem it's a good plan to first create an interface for your model and have your
concrete model implement this interface. This way it'll be easy to inject your model across various object
instances in your application. The injection bit we will come to later on. First let's create a very simple
model interface:

public interface IApplicationModel extends IEventDispatcher {

function get productItems():ArrayCollection;

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

And have your actual ModelLocator implement this, like so:

public class ApplicationModel extends EventDispatcher implements IModelLocator, IAp

private static var _modelInstance : IApplicationModel;

public static function getInstance():IApplicationModel {

91
Spring Actionscript extensions

if (!_modelInstance) {
_modelInstance = new ApplicationModel();
}

return _modelInstance;
}

public function ApplicationModel():void {


super();
if (_modelInstance) {
throw new Error('Only one ApplicationModel instance should be instantia
}
}

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"));
}
}
}

That was easy enough right? Now let's add a bit of XML to our application configuration that will make
sure a model instance is created:

<object id="appModelInstance" class="com.myclasses.cairngorm.ApplicationModel" fact

When transferring responsibility for creating our model to the IoC container, it is not even necessary
anymore to use the getInstance() factory method. Spring Actionscript will make sure only one instance
of the model is created. (Notice the singleton="true" attribute). So in all fairness, we can just change our
model class into this:

public class ApplicationModel extends EventDispatcher implements IModelLocator, IAp

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;

92
Spring Actionscript extensions

dispatchEvent(new Event("productItemsChanged"));
}
}
}

And change our configuration by getting rid of the factory method call:

<object id="applicationModel" class="com.myclasses.cairngorm.ApplicationModel" scop

That's it! Next up we are going to configure our FrontController and ServiceLocator.

The FrontController
When using Cairngorm without Spring Actionscript you are used to adding MXML instances of the
FrontController and ServiceLocator to your application like this:

<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>

After that you hook up your events and commands in your FrontController in more or less this fashion:

public class Controller extends FrontController {

public static const SOME_ACTION:String = "SomeActionEventID";

//-----------------------------------------------------------

public function Controller() {


super();
initializeCommands();
}

//-----------------------------------------------------------

public function initializeCommands():void {


addCommand( Controller.SOME_ACTION, SomeActionCommand );
}
}

And your service locator implementation will probably look something like this (depending on which
server technology is being used):

<cairngorm:ServiceLocator
xmlns:cairngorm="com.adobe.cairngorm.business.*"
xmlns:mx="http://www.adobe.com/2006/mxml">

<mx:RemoteObject id="SomethingRemote"
endpoint="/flex2gateway/"

93
Spring Actionscript extensions

destination="ColdFusion"
source="com.myremoteobjects.someservice"
concurrency="multiple"
makeObjectsBindable="true"
showBusyCursor="true"/>

</cairngorm:ServiceLocator>

Now this is all fine and dandy, but of course we would really like to keep configuration outside of our
compiled code. Otherwise every time we'd like to change an event/command combination we'd have to re-
compile the application. So, this is where the CairngormFrontController comes in. This class allows you
to pass an object as a parameter to its constructor which holds a mapping of event id's and commands.

To configure the instantiation of the CairngormFrontController in Spring Actionscript add this snippet of
XML to your configuration:

<object id="frontController" class="org.springextensions.actionscript.cairngorm.con


<constructor-arg>
<object>
<!-- Add a new property for each event/command mapping: -->
<property name="SomeActionEventID" value="SomeActionCommand"/>
</object>
</constructor-arg>
<!-- The following argument is optional -->
<constructor-arg value="com.mycommands.command"/>
</object>

The first argument is the object that contains the mapping between the event names and the command
classes. The second argument is optional and defines the package where the command classes reside. By
specifying this argument, you don't need to define the fully qualified class names of the commands.

We can now leave out the FrontController class, but beware: we need to make sure that the command
classes get compiled in the swf of our application. We can do this by referencing them in our application.
We'll also reference the CairngormFrontController class:

private var _cairngormFrontController:CairngormFrontController;


private var _commands:Array = [SomeActionCommand];

The MXML declarations of the FrontController and ServiceLocator have become obsolete by now, so let's
get rid of them:

<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>

Batch command support

In some cases its not necessarily convenient to have a separate event for every command that you want
to execute. Especially in bootstrap scenario's it can come in handy if a single event can trigger several

94
Spring Actionscript extensions

commands. For instance, an event called ExecuteBootstrapEvent triggers a command that retrieves the
locale data, one for default user settings, etc, etc.

The CairngormFrontController supports this behaviour by default. It is determined by the


allowCommandBatches property which is set to true by default.

What this does is allow you to associate more than one command with a single event, in the configuration
markup this is done simply like this:

<object id="frontController" class="org.springextensions.actionscript.cairngorm.con


<constructor-arg>
<object>
<!-- Add a new property for each event/command mapping: -->
<property name="SomeActionEventID" value="SomeActionCommand"/>
<property name="SomeActionEventID" value="AnotherActionCommand"/>
</object>
</constructor-arg>
</object>

Now, when a CairngormEvent is dispatched with the id SomeActionEventID, both the


SomeActionCommand and AnotherActionCommand classes will be created and executed.

Note
Another way of treating this scenario is to use an EventSequence, as described in the section
'Event Sequences'.

Module support in the CairngormFrontController


One big drawback and limiting factor of the regular FrontController is that it doesn't play nice in a multiple
module scenario. Meaning, in the case where two FrontController instances are created for two different
modules, yet both instances have associated a command with the same event id, this will actually trigger
both commands when this specified event is dispatched. The reason for this is the dependency that the
FrontController has on the CairngormEventDispatcher, which is a singleton. So both controllers will listen
for the same event from one instance of the CairngormEventDispatcher.

An example of this behavior could be an event that retrieves module settings. (Not too uncommon).
Imagine that this event has an id called "GetSettingEventId". Now the first module loads, its
FrontController gets instantiated and then some time after this the GetSettings event is dispatched. So far
so good, the FrontController detects the event being dispatched and executes its associated GetSettings
command which in turn calls a delegate, etc. However, when a second module gets loaded which also
needs to retrieve its settings both controllers will detect the GetSettings event and both of them will execute
their command. Which will lead to all kinds of interesting results you might imagine.

Naturally it would be desirable to somehow associate a FrontController with a specific module and when
events are dispatched within this module only the associated controller will be triggered.

Spring Actionscript's CairngormFrontController offers support for multiple module scenario's. This
functionality doesn't rely on a singleton event dispatcher but uses event bubbling instead. This does demand
a certain way of setting things up though and this section will show you exactly how.

Registering your module with the CairngormFrontController


After the CairngormFrontController has been created it needs to know in which module's context its
running. You can do this by invoking the CairngormFrontController's register() method and passing the

95
Spring Actionscript extensions

current module instance to it. As an example, imagine a module's CREATION_COMPLETE event handler
to be looking something like this:

public function creationComplete_handler(event:FlexEvent):void {


var frontController:CairngormFrontController = _applicationContext.getObject("modu
frontController.register(this);
}

After this the CairngormFrontController's instance will only be triggered by events that are dispatched
within this module's context.

Bubbling your Cairngorm events up to the CairngormFrontController


One thing you will have to make sure of is that your CairngormEvents are created with event bubbling set
to true and dispatched through one of the UI components dispatchEvent() invocations.

For example, if a button click needs to trigger a CairngormEvent, you used to dispatch it like this:

public function click_handler(event:MouseEvent):void {


CairngormEventDispatcher.getInstance().dispatchEvent(new MyCairngormEvent());
}

Or, you'd use the shorthand version:

public function click_handler(event:MouseEvent):void {


new MyCairngormEvent().dispatch();
}

The difference now is that you will dispatch the event through a UIComponent that is part of the display
hierarchy of the module, so instead you can dispatch the event like this:

public function click_handler(event:MouseEvent):void {


this.dispatchEvent(new MyCairngormEvent());
}

By default though, a CairngormEvent is created with its bubbling property set to false. So make sure that
CairngormEvents that are used in combination with the CairngormFrontController that uses a registered
module are always created with their bubbling property set to true.

var newEvent:MyCairngormEvent = new MyCairngormEvent("MyCairngormEventID",true);

For your convenience Spring Actionscript has a base class for this particular type of CairngormEvent called
SASCairngormModuleEvent. This CairngormEvent subclass has its bubbling property forced to true and
will throw an Error when the built-in dispatch() method is accidentally invoked.

If you are dispatching your Cairngorm events from a non-visual class, say a mediator or some subcontroller
you will have to make sure that this class has a reference to an IEventDispatcher instance that is part of
the UI hierarchy. Here's an example of a very simple mediator class:

public class ExampleMediator extends EventDispatcher implements IExampleMediator {

public function ExampleMediator(target:IEventDispatcher=null) {


super(target);
}

96
Spring Actionscript extensions

public function remoteOperation():void {


dispatchEvent(new MyCairngormEvent());
}

Now to make an instance of this class to bubble its events up the UI hierarchy create it with the module as a
constructor argument, so the module's CREATION_COMPLETE event handler could now look something
like this:

public function creationComplete_handler(event:FlexEvent):void {


var frontController:CairngormFrontController = _applicationContext.getObject("modu
frontController.register(this);

var exampleMediator:ExampleMediator = _applicationContext.getObject("exampleMediat


}

Injecting the module instance into the CairngormFrontController


Naturally the ideal situation would be where we can determine which module gets registered with which
CairngormFrontController using our beloved Spring Actionscript configuration markup. In this section we
show you one possible way of wiring up your objects using functionality that is already a part of Spring
Actionscript.

First of all we create a simple class that will be responsible for receiving a module instance and somehow
associate this with a particular CairngormFrontController. Let's say this class looks like this:

public class CairngormFrontControllerWireAgent implements IObjectFactoryAware {

private var _moduleMap:Dictionary;


private var _objectFactory:IObjectFactory;

public function ModuleFrontControllerWireAgent(moduleMap:Dictionary){


Assert.notNull(moduleMap,"moduleMap argument must not be null");
_moduleMap = moduleMap;
}

public function evaluate(component:Object):void {


Assert.notNull(_objectFactory,"_objectFactory must not be null");
var module:Module = (component as Module);
if (module != null) {
var name:String = module.name;
var frontControllerName:String = _moduleMap[name];
if (frontControllerName != null) {
var frontController:CairngormFrontController = _objectFactory.getObject(frontCo
if (frontController != null){
frontController.register(module);
}
}
}
}

public function set objectFactory(value:IObjectFactory):void {


_objectFactory = value;
}

97
Spring Actionscript extensions

Note
Notice the use of the Assert.notNull() method, this is part of the as3commons-lang library, for
more information about this Spring Actionscript spin off visit

As you see this class receives a dictionary as a constructor argument, this dictionary is a collection of
module name / FrontController name key-value pairs. To configure this class using Spring Actionscript
markup your configuration might look something like this:

<object id="frontcontrollerWireAgent" class="com.classes.CairngormFrontControllerWi


<constructor-arg>
<dictionary>
<entry key="mymodulename" value="frontcontrollerA"/>
</dictionary>
</constructor-arg>
</object>

<object id="frontcontrollerA" class="org.springextensions.actionscript.cairngorm.co


<!-- configuration omitted for brevity -->
</object>

Now only remains the question when and how to let the CairngormFrontControllerWireAgent work its
magic, for this last task Spring Actionscript already offers the StageComponentInterceptionPostProcessor
class. (See the section 'Injecting stage components into other objects' and 'The stage interception schema'
for the complete lowdown on this class).

Let's dive right in and show how to configure this class to leverage a CairngormFrontControllerWireAgent
instance:

<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.
http://www.springactionscript.org/schema/objects/spring-actionscript-stageinterce

<object id="frontcontrollerWireAgent" class="com.classes.CairngormFrontControllerW


<constructor-arg>
<dictionary>
<entry key="mymodulename" value="frontcontrollerA"/>
</dictionary>
</constructor-arg>
</object>

<object id="frontcontrollerA" class="org.springextensions.actionscript.cairngorm.c


<!-- configuration omitted for brevity -->
</object>

<si:stageinterceptor target-object="frontcontrollerWireAgent" target-method="evalu


object-selector="moduleSelector" id="stageInterceptor"/>

98
Spring Actionscript extensions

<object id="moduleSelector" class="org.springextensions.actionscript.ioc.wire.Type


<constructor-arg>
<array>
<value type="class">mx.modules.Module</value>
</array>
</constructor-arg>
</object>

</objects>

And that's the gist of it, right after your module has been loaded and added to the stage the stage interceptor
kicks into gear and makes sure the CairngormFrontControllerWireAgent performs the necessary injections
and you're good to go.

The ServiceLocator
Now what about that ServiceLocator? Having all that remoting configuration right inside your source code
is also not very convenient. What if the paths are different between staging and production servers? What
if you'd like to change the remote path later on while already being in production? Right now all of those
changes would require a re-compile of the application. A re-compile that is unnecessary when you use
Spring Actionscript to configure your ServiceLocator.

To be able to configure the services at runtime Spring Actionscript offers a subclass of the normal
ServiceLocator that allows just this. The class we're talking about is the CairngormServiceLocator. To
have the container create an instance of this class, add this bit of markup to your application configuration.

<object id="serviceLocator" class="org.springextensions.actionscript.cairngorm.busi


<!-- The CairngormServiceLocator is marked with the dynamic keyword, so new prope
<property name="testService">
<ref>testService</ref>
</property>
</object>

As you'll notice by the <ref/> element used in the testService property, this ServiceLocator already has
one service configured.

The testService (RemoteObject) instance is defined like this:

<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>

Of course, afterwards make sure the appropriate classes are referenced in your source code, otherwise you
will experience run-time errors because the classes will not have been compiled into your swf:

private var _cairngormFrontController:CairngormFrontController;


private var _cairngormServiceLocator:CairngormServiceLocator;
private var _remoteObject:mx.rpc.remoting.mxml.RemoteObject;

99
Spring Actionscript extensions

private var _commands:Array = [SomeActionCommand];

Channel configuration
But wait a minute, that RemoteObject right now makes use of the default configured channel set in Flex,
how about we pull that into our configuration as well?

Doing this is quite easy, just add this bit of XML:

<object id="amfChannel" class="mx.messaging.channels.AMFChannel" scope="singleton">


<constructor-arg value="my-amf"/>
<constructor-arg value="http://{server.name}:{server.port}/flex2gateway/"/>
<property name="id" value="amfChannel"/>
<property name="pollingEnabled" value="false"/>
</object>

<object id="channelset" class="mx.messaging.ChannelSet" scope="singleton">


<method-invocation name="addChannel">
<arg>
<ref>amfChannel</ref>
</arg>
</method-invocation>
</object>

And add an extra property to your RemoteObject configuration, like this:

<object id="testService" class="mx.rpc.remoting.mxml.RemoteObject">


<property name="id" value="testService"/>
<property name="destination="ColdFusion"/>
<property name="source" value="com.myremoteobjects.someservice"/>
<property name="showBusyCursor" value="true"/>
<property name="makeObjectsBindable" value="true"/>
<property name="channelSet">
<ref>channelset</ref>
</property>
</object>

Spring Actionscript also offers some convenience markup to make configuring channels a little easier. See
the section 'The messaging schema' for more information.

RemoteObject template
Now there's a fair chance that this will not be the only RemoteObject that you'll be using in your application,
usually there's a multiple of them. Let's add a template to the configuration that will save a bit of typing
when adding new ones:

<template id="remoteObject">
<object class="mx.rpc.remoting.mxml.RemoteObject" scope="singleton">
<property name="destination" value="ColdFusion"/>
<property name="source" value="com.myremoteobjects.${serviceClass}"/>
<property name="channelSet">
<ref>channelset</ref>
</property>
</object>

100
Spring Actionscript extensions

</template>

Now you can change the configuration for the testService into markup that looks like this:

<object id="testService" template="remoteObject">


<param name="serviceClass" value="someservice"/>
</object>

Spring Actionscript also offers some convenience markup to make configuring remote objects a little
easier. See the section 'The RPC schema' for more information.

The Command Factory


The FrontController usually takes care of instantiating the command classes that are mapped to your events.
This starts to become inconvenient when a Command instance needs a reference to, for example, the
model instance. (A situation which will occur quite regularly.) Normally you would just add a direct
reference into your command class through a call to the applicationModel.getInstance() method. This is
what we call 'tight coupling' and is undesirable since it leaves the command directly dependent on a specific
implementation of the model class. For example, this will make unit testing the class a lot harder since
your unit test will be dependent on that same model instance.

So what we'd like to be able to do is inject this model instance into the command after it has been created.
Spring Actionscript offers the ICommandFactory interface to solve this problem.

The interface is very simple and requires only to implement two methods:

public function canCreate(clazz:Class):Boolean;


public function createCommand(clazz:Class):ICommand;

The result of the canCreate() method determines whether the specific command factory is able to create
the requested command class. In this method you could check if a command implements a certain interface
or look it up in a list of command classes that was injected at runtime.

If the canCreate() method returns true it will be save to call the createCommand() method which returns
the actual instance of the requested class.

The CairngormFrontcontroller actually creates an implementation of this interface internally. This


ICommandFactory implementation checks whether the specified class implements the ICommand
interface and creates the command or not accordingly.

Note
When you import both Cairngorm and Spring Actionscript you
will notice there are two definitions for the ICommand
interface, namely org.springextensions.actionscript.core.command.ICommand and
com.adobe.cairngorm.commands.ICommand. In this case you need to import the latter.

Now, to solve your little model injection problem, let's say you define a small interface called
IApplicationModelAware. The definition of which could simply be like this:

public interface IApplicationModelAware {

function set applicationModel(value:IApplicationModel):void;

101
Spring Actionscript extensions

Where the IApplicationModel is the interface you have created to describe your model.

Now you can go ahead and create a base class for all your commands that require a reference to the model:

public class CommandBase extends AbstractResponderCommand implements IApplicationMo

public function CommandBase() {


super();
}

private var _applicationModel:IApplicationModel;

function get applicationModel():IApplicationModel {


return _applicationModel;
}

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");
}

To be able to create subclasses of this command and inject them with a model reference we can now
construct an implementation of the ICommandFactory interface:

public class ApplicationModelAwareCommandFactory implements ICommandFactory, IAppli

public function CommandFactory() {


super();
}

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();

102
Spring Actionscript extensions

result.applicationModel = _applicationModel;
return result;
}
}

Note
You will notice the use of the ClassUtils class in this code example. This is part of the
as3commons-lang library, part of the as3commons library, which can be found here:

As you see the ApplicationModelAwareCommandFactory implements the same IApplicationModelAware


interface as well. Now, to be able to inject the model into our new factory and after that inject it into
our controller we need to add some XML to our application configuration. First let's create the command
factory:

<object id="appAwareCmdFactory" class="com.myclasses.cairngorm.factories.Applicatio


<property name="applicationModel" ref="appModelInstance"/>
</object>

Remember how we already added markup to instantiate our model? We now use the context id of that
object to inject it into our command factory.

Now we can change the XML markup that configures our controller:

<object id="frontController" class="org.springextensions.actionscript.cairngorm.con


<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 -->
<method-invocation name="addCommandFactory">
<arg><ref>appAwareCmdFactory</ref></arg>
</method-invocation>
</object>

And there we are! From now on every command that is added to our FrontController (and subclasses the
CommandBase class) will be automatically injected with the ApplicationModel instance after creation.

Using the application context as a command factory


Its unnecessary to create an ICommandFactory if the injections can be expressed in the XML
configuration. In this case, just define the definitions for the commands in the application context and add
them to the front controller like this:

<object id="someActionCommandID" class="com.class.commands.MyCommand">


<!-- omitted configuration -->
</object>

<object id="frontController" class="org.springextensions.actionscript.cairngorm.con


<constructor-arg>
<object>
<property name="SomeActionEventID" value="someActionCommandID"/>

103
Spring Actionscript extensions

</object>
</constructor-arg>
</object>

The Delegate Factory


Cairngorm commands need delegates, these delegates are responsible for retrieving and sending the data
in the application. One way to do this is to create an instance of a specific delegate inside the command
class. Let's create an example command class that handles the retrieval of products:

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 = 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
}

Again this tightly couples the command to a specific delegate. For example, what if we want to replace
this delegate with a mock version that simply returns test data? What is needed, again, is an interface, one
that describes the functionality of our delegate. Spring Actionscript already offers an interface that we can
use as a base for this. Its called IBusinessDelegate.

The GetProductItemsDelegate declaration could look a little like this:

public interface IGetProductItemsDelegate extends IBusinessDelegate {

function getProductItems():void;

An implementation of the interface can conveniently inherit from the already available
AbstractBusinessDelegate class:

public class GetProductItemsDelegate extends AbstractBusinessDelegate {

public function GetProductItemsDelegate(service:* = null, responder:IResponder


super(service, responder);

104
Spring Actionscript extensions

public function getProductItems():void {


var token:AsyncToken = service.getProductItems();
token.addResponder(this.responder);
}
}

Now its time to change the base command class. You can see we were already inheriting from
the AbstractResponderCommand class provided by Spring Actionscript. This class already exposes a
property called businessDelegate which expects an instance of IBusinessDelegate. Since we made our
IGetProductItemsDelegate inherit from this interface we can use this property in our command class. We
can delete the creation of the delegate altogether and simply cast the value of the businessDelegate property
to our own delegate interface.

We'll make sure an appropriate instance will be injected later on, first let's change our command into this:

public class GetProductItemsCommand extends CommandBase {


public function GetProductItemsCommand() {
super();
}

override public function execute(event:CairngormEvent):void {


super.execute(event);
//execute the delegate logic
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
}
}

Nothing fancy there either, actually we just made our class smaller which always good, right?

Now we want to be able to create an instance of the GetProductItemsDelegate and inject it into
our GetProductItemsCommand once its created by the command factory. Luckily Spring Actionscript
already offers a class that performs exactly this task for you. The ResponderCommandFactory class
to be precise. This class (an implementation of IResponderCommandFactory) has a method called
addBusinessDelegateFactory() which expects an instance of IBusinessDelegateFactory and an array of
command classes.

Before we forget, first let's change the implementation of our command class so that it inherits from
ResponderCommandFactory:

public class ApplicationModelAwareCommandFactory extends ResponderCommandFactory im

public function CommandFactory() {


super();
}

105
Spring Actionscript extensions

private var _applicationModel:IApplicationModel;

function set applicationModel(value:IApplicationModel):void {


_modelInstance = value;
}

override public function canCreate(clazz:Class):Boolean {


//First check if we can create the specified class, then ask our super clas
if (ClassUtils.isSubclassOf(clazz, CommandBase)) {
return super.canCreate(clazz);
}
return false;
}

override public function createCommand(clazz:Class):ICommand {


//First have our super class create and inject an instance, after that we p
var result:CommandBase = super.createCommand(clazz) as CommandBase;
result.applicationModel = _applicationModel;
return result;
}
}

Well, then it is finally time to tie everything together and the place to do this of course is the Spring
Actionscript configuration.

First of all, let's define our BusinessDelegate factory:

<object id="businessDelegateFactory"
class="org.springextensions.actionscript.cairngorm.business.BusinessDelegateFact
<property name="service" ref="testService"/>
<property name="delegateClass" type="class" value="com.myclasses.delegates.GetPro
</object>

After that we can create the new command factory and add our business delegate factory to it, along with
the name of our command classes. (well, in our case just one command class). To do this we change our
existing definition we created earlier:

<object id="appAwareCmdFactory" class="com.myclasses.cairngorm.factories.Applicatio


<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>

By passing a reference to our businessDelegateFactory to the addBusinessDelegateFactory() method along


with the classname of our command, we tell the command factory that each time he creates an instance of
our command he can use the business delegate factory to create a delegate for it. If more command classes
use the same delegate, just add their class to the array of class names. If a different delegate is needed

106
Spring Actionscript extensions

than add another definition to your application configuration. And if more complex injection needs to be
performed, go right ahead and subclass the existing Spring Actionscript extensions for your convenience.

And there we are, our complete Cairngorm configuration is now loosely coupled and fully managed by
the Spring Actionscript container!

Now go ahead and start coding!

The IDataTranslator interface


When dealing with web services you will typically receive a response that consists of an XML string (but
other formats such as JSON, CSV or anything else are possible too of course). This XML is not particularly
useful within an application so naturally this XML will need to be converted into business or value objects.
You can choose to perform this conversion either in your delegate or your command class after a response
has been received. However, these classes aren't really meant to perform this task, and that's why Spring
Actionscript offers the IDataTranslator interface.

The interface, as usual, is a very simple one:

public interface IDataTranslator {


function translate(data:*):*;
}

This enables an IDataTranslator implementation to take a generic input and return a generic output.

Now what we'd like to be able to do is inject an IDataTranslator into a delegate instance when appropriate,
since not all delegates will need one naturally. So, what we need is a delegate instance that implements
the IDataTranslatorAware interface.

This particular interface will not make you scream in terror of its complexity either:

public interface IDataTranslatorAware {


function set dataTranslator(value:IDataTranslator):void;
}

Spring Actionscript offers a base class for such a delegate called


AbstractDataTranslatorAwareBusinessDelegate. If you want to create a delegate that makes use of an
IDataTranslator implementation then simply derive from this class. Here's a simple example of an
AbstractDataTranslatorAwareBusinessDelegate subclass:

public class GetProductsDelegate extends AbstractDataTranslatorAwareBusinessDelegat

public function GetProductsDelegate(service:*=null, responder:IResponder=null, da


super(service, responder, dataTranslator);
}

public function getProducts():void {


var token:AsyncToken = service.getProducts();
addResponderToToken(token);
}
}

Notice the one line in bold, this is where we call a method in the base class that takes care of intercepting
the service call, sending the input to the assigned IDataTranslator and afterwards sending its result back
to the delegate's responder.

107
Spring Actionscript extensions

Now, a simplified implementation of an IDataTranslator that takes an XML response and turns it into an
array of objects is shown below:

public class XMLToProductsDataTranslator implements IDataTranslator {

public function XMLToProductsDataTranslator() {


}

public function translate(data:*):* {


var productsArray:Array = [];
var productsXML:XML = new XML(data);

//Conversion logic omitted for clarity...

return productsArray;
}
}

To configure the delegate to use this particular IDataTranslator you can add this bit of markup to your
configuration file:

<object id="productTranslator" class="com.mytranslators.XMLToProductsDataTranslator

<object id="productsDelegate" class="com.mydelegates.GetProductsDelegate">


<property name="dataTranslator" ref="productTranslator"/>
</object>

Or you can create your own version of the delegate factory that handles this kind of injection.

Note
Credit where credit is due: This addition to the Spring Actionscript Cairngorm extensions was
inspired by this blog post by Adam Flater:

Event Sequences
Problem

We want to be able to execute commands in a sequence, where each command needs to be executed after
the previous command has finished. This can be right after a call to execute() in case the command only
implements ICommand, or after the invocation of the result() or fault() method, in case the command
implements the IResponder interface and fetches some remote data.

The way to do this in Cairngorm is to let your command extend SequenceCommand - which acts as an
abstract base class for commands that are executed in a sequence. Then you assign a value to the nextEvent
property and call the executeNextCommand() method. This is done in the execute() method, the result()
or fault() handler of the command. Each sequence command contains logic that says which command to
execute next.

This has a major drawback though: since the sequence logic is coded in the commands themselves, it is
very hard - not to say impossible without extra conditional logic - to reuse the command outside a sequence
or in another sequence.

Solution

108
Spring Actionscript extensions

Instead of extending SequenceCommand and coding the sequence logic in the commands themselves,
let's define a sequence of events outside of the commands. The commands themselves should not extend
SequenceCommand. This will allow to create "standalone" commands that have their specific task and
then chain them into a variety of sequences.

Explanation

The solution Spring Actionscript offers comes in the form of the EventSequence class. As said earlier,
we want to have a non-intrusive way of defining sequences of events/commands without the need to code
sequence logic in the commands. As an example, let's take an event that causes the user to log in, after
which another event is dispatched to fetch the latest private messages for that user. In Cairngorm we would
have the following:

public function LoginCommand extends SequenceCommand implements IResponder {

// code left out...

public function result(data:Object):void {


var user:UserVO = data.result as UserVO;
ModelLocator.getInstance().user = user;
// here is the problem, the command knows what command to execute next
// we can't reuse this command in another chain
nextEvent = new LoadPrivateMessagesEvent(user.id);
executeNextCommand();
}

In the above code, the sequence logic in the result() handler prevents us from reusing the command outside
of the sequence or in another sequence. This will most often result in duplicate code which makes the
code base hard to maintain.

Looking at the flow of events and commands, we see that in most cases (but not all) a command will update
some property in the ModelLocator. This is a good practice, because it keeps your commands consistent
across your application: a command executes, proxies a remote call through a business delegate, adds itself
as a responder to the remote call, updates the ModelLocator in the result() or fault() handler.

Example

Let's dive into an example of the EventSequence. The different parts will be explained individually:

var sequence:EventSequence = new EventSequence();

//add a first event to the sequence which let's the user log in

sequence.addSequenceEvent(
LoginUserEvent,
[username, password]
);

//add a second event which fetches the latest private messages

sequence.addSequenceEvent(
LoadPrivateMessagesEvent,
[new Property(ModelLocator.getInstance, "user", "id")],

109
Spring Actionscript extensions

[new Property(ModelLocator.getInstance, "user")]


);

// start the sequence

sequence.dispatch();

Explanation

First thing we need to do of course is create a sequence. We can do this by creating an instance of
EventSequence.

Next, the sequence expects us to define different events in it so that it knows when to fire which event.
We do this by calling addSequenceEvent() on the sequence and passing in the properties of the event we
want the sequence to dispatch.

sequence.addSequenceEvent(
LoginUserEvent,
[username, password]
);

The first argument is the class of the event. In our case this is LoginUserEvent with has 2 constructor
parameters: username and password. These parameters are defined in the second argument of the
addSequenceEvent() method as an array.

There are 2 options:

1. we pass in concrete values

2. we pass in an instance of Property which let's us define a lookup of a property (if you are familiar with
BindingUtils, you will already know how this works)

The first option, passing in a concrete value, is quite straight forward. In case of the LoginUserEvent we
pass in the credentials of the user, which will normally be fetched from the text inputs of the login form.
So the definition of this could look as follows:

sequence.addSequenceEvent(
LoginUserEvent,
[username, password]
);

The second option is a property that will be evaluated or looked up at runtime and is defined by a host and
a chain. In case of the second event, we want to pass in the user's id, but we can only do this if the user
is defined in the ModelLocator and has a valid id (this will be after executing the LoginUserCommand).
Doing the following wouldn't work (don't worry about the 3rd argument for now):

sequence.addSequenceEvent(
LoadPrivateMessagesEvent,
[ModelLocator.getInstance.user.id],
[new Property(ModelLocator.getInstance, "user")]
);

This will result in a runtime error (null pointer exception) because we want to pass in the concrete value of
the user's id when we define the sequence. Since the ModelLocator does not contain a valid user instance
at that point, this won't work. Therefor we need to define the value as a property of which the value will
be "looked up" when we really need it (that is when firing the next event in our case).

110
Spring Actionscript extensions

The property defines a host: that is the variable that contains - or better will contain - the needed parameters
for the event. In our case this is the model locator, so ModelLocator.getInstance(). The remaining
arguments of the property instance are a chain of properties of the host defined as strings. So to get the
user's id from the model locator we would define the following:

var p:Property = new Property(ModelLocator.getInstance(), "user", "id");

The third argument of the addSequenceEvent() defines a trigger that will instruct the next event to be fired.
In the example above, the next event will get fired when the user property of the model locator has changed.

After we have defined the sequence, all we need to do is call it's dispatch method. Also, the event/command
mapping is still defined in the front controller, just like you would do without sequences. There is no need
to specify any custom mapping.

Where to create sequences?

Normally one would create a subclass of EventSequence and define the sequence in the constructor. One
would then instantiate the sequence in the appropriate view and dispatch it from there.

An alternative approach could be that the front controller has support for defining sequences. We would
then have a centralized place for specifying these sequences instead of having them scattered in different
classes. In this case there should also be a way of launching a sequence from the view. There's no such
feature yet in the Spring Actionscript extensions but if enough requests are made by the community they
can be implemented in due time.

What if the command does not update the model locator.

There will be times when a command does not update a property in the model locator. So we
don't really have a point in time when we know we should trigger the next event. To solve this,
the CairngormFrontController registers every executing command in a central registry called the
PendingCommandRegistry. The command then has do decide when its action is finished and unregister
itself:

public function result(data:Object):void {


// do some stuff
// ... now let the sequence know this command is done
// we do this indirectly by unregistering
PendingCommandRegistry.getInstance().unregister(this);
}

When calling unregister, the event sequence will get notified of this and trigger the next event if any.

PureMVC
The following section documents the functionality and ideas behind the Spring Actionscript PureMVC
extensions as written by their main author Damir Murat.

Note
The sample projects for the PuremVC extensions can be found in this .

General notes, intentions, plans and vision


After some learning, investigation and playing with Flex and ActionScript 3, I've headed toward finding
ways which can simplify implementation of large-scale enterprise applications in Flex. Why is this needed?

111
Spring Actionscript extensions

Well, I see Flex as a so called "application framework" which can significantly simplify attractive GUI
creation, but it doesn't really help in application structuring. That application structure and architecture
are important in big projects for various reasons. Most notably, it provides maintainability and scalability
of an application code, but it also defines rules and patterns which can serve as a common denominator
for a development team.

In that area I've found only two prominent candidates at the time: Adobe's Cairngorm and PureMVC. I
first tried Cairngorm, but I didn't really like it, so I tried PureMvc next. In my opinion, PureMvc represents
a very solid foundation for building Flex applications. It is well structured and designed, created around
core interfaces which define main framework rules, and it certainly can provide the structure needed for
many non trivial applications. It is also very well documented.

While I was going through the PureMvc documentation and samples, I was a little bit surprised to see
that the PureMvc applications are usually coded to concrete classes instead to interfaces. For example, the
typical PureMVC idiom for using a registered proxy instance is to write something like this in a command:

public class DeleteUserCommand extends SimpleCommand implements ICommand {

override public function execute(notification:INotification):void {


var user:UserVO = notification.getBody() as UserVO;
var userProxy:UserProxy = facade.retrieveProxy(UserProxy.NAME) as UserProxy;
var roleProxy:RoleProxy = facade.retrieveProxy(RoleProxy.NAME) as RoleProxy;
userProxy.deleteItem(user);
roleProxy.deleteItem(user);
sendNotification(ApplicationFacade.USER_DELETED);
}
}

Note
The code is taken from the PureMVC Arch101Demo sample

Here you can find the dependencies to the concrete classes UserProxy and RoleProxy. Of course, this
particular case can be refactored to the interfaces, but I'm just trying to illustrate the common usage.
Further, it will be ideal if you have an ability just to express the dependencies through setters and getters
and that some external entity fulfills them by injecting them automatically at runtime. In such scenario,
your command will not be dependent on concrete classes, and at the same time it will not be dependent
on framework infrastructure like facade. Then, you will be able to code this command to look something
like following:

public class DeleteUserCommand extends SimpleCommand implements ICommand {

private var m_userProxy:IUserProxy;


private var m_roleProxy:IRoleProxy;

public function set userProxy(p_userProxy:IUserProxy):void {


m_userProxy = p_userProxy;
}

public function set roleProxy(p_roleProxy:IRoleProxy):void {


m_rolePrxy = p_roleProxy;
}

override public function execute(notification:INotification):void {


var user:UserVO = notification.getBody() as UserVO;

112
Spring Actionscript extensions

userProxy.deleteItem(user);
roleProxy.deleteItem(user);
sendNotification(ApplicationFacade.USER_DELETED);
}
}

Now, the dependencies on concrete classes and framework infrastructure (i.e. facade) are gone from your
code, and automatically it is much more maintainable, scalable and testable.

To my knowledge, to achieve something like this with PureMVC is not easy and will require very careful
refactoring and recoding of the internal concrete PureMVC classes like Model, View and Controller (I
believe that the core PureMVC interfaces can be left intact). Probably, it is not bad to put high goals as
long they do not scare you, but to be on a safe route, we can try to achieve something much easier. Let
me try to explain with an example.

In my first PureMVC experiment (which was really not so simple I must say), I have to code a proxy class
which can load some remote data encoded in XML and convert it in an internal domain model which is
usually termed as value objects in PureMVC. Actually domain model and value objects are not the same at
all, but they do not differ in the context of this discussion. So, I didn't want to complicate my project with
a server side, and I ended up with local XML files. I've also used the loading delegate pattern known from
Cairngorm. A loading delegate handles all communications and conversion of encoded data in the domain
model. At the end, I've implemented a method in a proxy class which looks something like following:

public function loadCandlestickCollection(p_stockSymbol:StockSymbol):void {

LOGGER.debug("Loading candlestick collection for stock symbol " + p_stockSymbol.s

LOGGER.debug("Notifying observers with " + LoadDataNotification.NAME + "." + Load


facade.notifyObservers(new LoadDataNotification(null, LoadDataNotification.TYPE_S

var delegate:CandlestickLoadDelegate = new CandlestickLoadDelegate(this);


delegate.load(p_stockSymbol);
}

Here, CandlestickLoadDelegate is the concrete class which I don't like very much. I mean, I was just
prototyping, and this local data loading delegate will be changed in the final version with its remoting
equivalent. This will require either refactoring of the proxy method (and implementation of another loading
delegate) or refactoring of the current concrete loading delegate. It will be much better to introduce an
appropriate loading delegate interface. This can be done with any variation of the factory pattern, but this
typically only moves the concrete class dependency in the factory. It will be much better if I have some
general purpose factory (which can be configured, not coded) from which I can fetch the dependencies as
needed. Something like Spring, but in Flex/AS3 world. For the further reference I will name this type of
usage of an IoC container (which has the role of the general purpose configurable factory in this context)
as the "ad hoc IoC container usage". It will be helpful if such ad hoc usage can be enabled in a consistent
manner, for example as a built-in feature of the extended PureMvc framework. I believe that this can be
done fairly easily if I have a good IoC container at disposal.

As it turns out, there is a good IoC container available in Flex world, it is called Spring Actionscript.
There are also some others, but Spring Actionscript has several releases, decent documentation, and a very
competent, friendly and collaborative lead developer. All in all I decided to try it in a general manner, and
specifically, to try to integrate it with PureMVC.

So, I decided to organize my PureMVC/Spring Actionscript integration endeavour in three steps in which
I will try to achieve different levels of integration, from easier to harder, of course. It is important to
emphasize that I will try not to change the basic PureMVC programming model. I don't want to create

113
Spring Actionscript extensions

a new MVC framework, I just want to integrate Spring Actionscript with PureMVC. That said, it is still
expected that some minor changes in the common PureMVC usage patterns will be required.

In the first level of integration I will just try to bring Spring Actionscript in PureMVC as an additional
property of the PureMVC facade. That way a developer can use Spring Actionscript in the consistent ad hoc
meaner when he needs it. Typically, the container will not contain any configurations of a PureMVC triad
(proxy, mediator, command), but only their external dependencies (this should be easy enough, but you
never know). Additionally, I expect that this level of integration will require minor changes in the typical
PureMVC application's startup procedure. This is caused with asynchronous nature of the container's
startup while it reads configuration files.

If only that first integration level will be all that I can achieve, I will be satisfied enough because I believe
that by them self it can significantly help in my future Flex projects.

In the second level of integration I plan to bring Spring Actionscript and PureMVC closer, with some
functionality which will help to configure the PureMVC elements in Spring Actionscript. Since PureMVC
maintains its own object container (at least for proxies and mediators), at this moment I am planning to
take into account only objects configured as prototypes (not singletons). While doing this, I'm hoping to
learn much more about repercussions that singletons will bring to table, since at least, I expect that some
synchronization between Spring Actionscript and PureMVC container will be needed. Hopefully, at the
time you will read this, both prototypes and singletons will be equally supported.

With only prototypes supported, Spring Actionscript will not have to manage the PureMVC elements, but
rather it will only create them and hand them over to PureMVC. Naturally, this still will be the ad hoc
usage of the container and it can be programmed with only "Level 1 integration" available. However, I
plan to add some methods in the PureMVC facade which should be helpful in the process. Support for
singletons is left for the third level of integration, but it can happen sooner, you never know.

During second phase of integration I expect to learn a great deal about Spring Actionscript's and
PureMVC's internal workings. I also expect that the "Level 2 integration" will be much harder to implement
than the level one. The typical PureMVC usage patterns will probably stay intact, they just can be
implemented through facade's methods with new names. The original PureMVC API will not change, so
if you can't find any benefits in the "Level 2 integration", simply just don't use it.

So we came to the third level of integration. In this phase I plan to fully integrate PureMVC and
Spring Actionscript in a way that should be hard to define borders between the Spring Actionscript's
and PureMVC's containers. All PureMVC elements should be freely configurable through Spring
Actionscript either as prototypes or singletons, depending on application's needs. Framework dependencies
in application should be minimal in a way that you no longer need to retrieve the PureMVC elements
from the PureMVC facade. The dependencies will be injected automatically. Of course, there still will be
need to interact with the facade during registration and notification processes. This kind of IoC usage is
no longer the ad hoc usage. This is usage of the IoC container at its full potential. We will see if I'm able
to implement something like this. :-)

This whole endeavour is highly experimental, so I decided not to develop it in the typical framework style.
This is left for later if and when this experiment can be considered as a success. Instead I will take the
referential PureMVC Arch101Demo sample, and start to modifying it.

Implementation notes and steps


Level 1 integration
• Creation of Spring Actionscript/PureMVC integration packages
(org.springextensions.actionscript.puremvc) with subpackage structure corresponding to the internal
PureMVC package structure.

114
Spring Actionscript extensions

• Creation of the IocFacade class which, at the moment, have the same API as the original PureMVC
facade. IocFacade implements the IIocFacade interface which is extended from the original PureMVC
IFacade interface. The IocFacade implementation mainly consists of a copied and refactored code from
the PureMVC Facade class. At this point I didn't extend it because I expect that implementation of
IocFacade can be significantly changed in the future, possibly in a way where inheriting from original
Facade class could prevent adding some functionalities. Of course at this point I can't be sure at this,
so it could be changed. Actually, if possible, inheriting original Facade call will be beneficial for many
reasons (less lines of code, improved maintainability, fewer bugs, easier update route etc.), so I will
definitely look at it, but currently, I guess I will like as much freedom as possible. When reading this,
one should check the source to see actual situation. However, no matter which implementation options
is chosen, client API should stay the same, which means, actual implementation will not have influence
on applications which will try to use Spring Actionscript/PureMVC integration.

Currently, the most notable difference between APIs of original Facade and IocFacade is in constructor
because IocFacade requires a string parameter for URL of an XML file with the Spring Actionscript
(IoC) configuration.

• Consequently, the common startup PureMVC idiom is now changed a little. Instead of writing something
like this:

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="onCre


<mx:Script>
<![CDATA[
...
private var m_facade:ApplicationFacade = ApplicationFacade.getInstance();
...
private function onCreationComplete(p_event:Event):void {
m_facade.startup(this);
}
]]>
</mx:Script>
...
</mx:Application>
You are now required (because of an asynchronous configuration reading) to write something like
following:

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="onCre


<mx:Script>
<![CDATA[
...
private var m_facade:ApplicationFacade;
...
private function onCreationComplete():void {
m_facade = ApplicationFacade.getInstance("applicationContext.xml");
m_facade.addEventListener(ObjectDefinitionsLoaderEvent.COMPLETE, startupA
}

private function startupApp(p_event:ObjectDefinitionsLoaderEvent):void {


m_facade.removeEventListener(ObjectDefinitionsLoaderEvent.COMPLETE, start
m_facade.notifyObservers(new Notification(ApplicationFacade.STARTUP, this
}
]]>
</mx:Script>
...

115
Spring Actionscript extensions

</mx:Application>

• In IocFacade additional getter is added for accessing "container" property.

• Also, additional property "iocFacade" is added in IocProxy, IocMediator, IocSimpleCommand


and IocMacroCommand. It enables easy access to the IoC facade (and to the IoC container through
it) from concrete implementation classes. Hopefully, all that will bring some consistency in the ad hoc
usage of the IoC container in PureMVC applications.

• Few IIoC* interfaces are added. In this phase they are merely a placeholders for the extended API
methods that should appear in the following integration phases.

• Concrete implementation classes IocProxy, IocMediator and Ioc*Command deliberately are not
extended from the original PureMVC counterparts at this point, mainly for the same reasons as for
IocFacade. Additional problem is in the PureMVC implementation of Notifier class which defines
the protected "facade" member and causes currently unnecessary instantiation of the original IFacade
instance. Still, authentic contracts defined through PureMVC interfaces are left intact. If possible, at
one point IocProxy, IocMediator and Ioc*Command will be extended from their original PureMVC
counterparts. If so, protected "facade" member will no longer be the problem.

• In Arch101Demo.mxml I added "linkageEnforcer" property to simplyfy linking of classes which are


mentioned only in IoC configuration. This linkage method should not be used for production purposes.
It will be much preferable to add these classes to the compiled swf automatically, solely based on IoC
configuration, without requiring any programming. Creating such a system is one of the pending tasks
which should make Spring Actionscript usage much more comfortable in general.

• To illustrate the "consistent ad hoc usage" of the Spring Actionscript container I've added
UserLoadDelegate class in "puremvcarch101Demo" application. UserLoadDelegate is used by
UserProxy to load user data from local XML file. UserLoadDelegate is configured in IoC configuration
and is used by proxy through IUserLoadDelegate interface.

Level 2 integration
• Before looking further at the integration, I will try to minimize dependencies on concrete classes in the
Arch101Demo sample.

• First on a list is the UserLoadDelegate class. Currently it has the "callback" dependency on the
UserProxy concrete class. To avoid that, I've refactored UserLoadDelegate to use events. That change
alone allows removal of the "userProxy" setter from the IUserLoadDelegate interface. Of course, now
is required that the UserProxy implements some event handling code but that is nothing new to Flex
developers. Further, I've also removed "serviceUrl" setter from the IUserLoadDelegate interface. It is
not required in application code and only Spring Actionscript needs it to inject dependency at runtime.
But for Spring Actionscript's needs, that setter doesn't have to be declared in the interface. It is enough
just to be implemented by concrete class which is configured through Spring Actionscript. In summary,
above changes left us only with loadUsers() method in the IUserLoadDelegate interface. I've also added
a simulation of the slow data loading in the UserLoadDelegate class to make it somewhat more realistic.

• Next I've created IUserProxy and IRoleProxy interfaces which will be used through the rest of an
application code instead of corresponding concrete classes. That also required refactoring of proxy
name constants in the separate ProxyNames class (constants can not be defined in ActionScript 3
interfaces). Now constants from this class will be used for proxy retrievals. The ProxyNames class, and
its encapsulated name constants, should be now viewed as a part of public API in the same way as proxy
interfaces are. NAME constants are removed from concrete proxy classes because they are not really
needed as we will see.

• To support above refactorings, I've added the registerProxyByConfigName() method in the IIocFacade
interface and the implementation in the IocFacade class. When you use this method, you must supply

116
Spring Actionscript extensions

proxy name as the parameter. IocFacade will try to find configuration whose id is equal to that parameter.
If it can't be found, an error will be thrown. On the other hand, if it can be found, IocFacade will retrieve
it from container and will set its name to the value of supplied parameter (which in this case must be the
same as the value of id attribute in configuration). Of course, you will not use literals for that parameter,
rather you will probably use constant defined in the public API as discussed before.

• Described usage of name constants is still a little bit too restrictive. Specifically, if you change the
configuration id, you must also change the name constant value. This is not so good, I think. It will be
better if there is no so tight coupling.

Now, what we can do? Well, we can try the old IT trick - introduction of another level of indirection. For
example, we can introduce a names map whose keys will be equal to values of constants defined in code,
and map values will be equal to ids. Then, you will be able to independently change configuration names
(which can be pretty often) and constant values (which is not so often, or almost never). To support this
idiom, I've changed implementation of registerProxyByConfigName() method in following way:

• If object with id "proxyNamesMap" can be found in the IoC configuration ("proxyNamesMap" is


magic name as you can observe), IocFacade will try to map supplied parameter (configured as a map
key) with mapped name (configured as a map value). If mapped name is found, then IoC facade will
try to retrieve configured proxy object whose configuration id attribute is equal to mapped value. If
configured proxy can be retrieved it will be returned. Otherwise, error will be thrown.

• If there is no "proxyNamesMap" object in the configuration, or if supplied parameter value is not used
as a map key, IocFacade will try to find proxy object whose configuration id attribute value is equal
to supplied parameter. If proxy can be found, it will be returned. Otherwise, error will be thrown.

• Corresponding retrieveProxyByConfigName() method is added in IIocFacade interface and in


IocFacade class. For retrieval it uses equivalent algorithm to the one described above.

Please note that retrieveProxyByConfigName() and removeProxyByConfigName() methods can be


removed from IIocFacade later if IocFacade will be extended from original PureMVC Facade,
and if their workflows can be combined with workflows of the original retrieveProxy() and
removeProxy() methods. Please take a look at source code to see what is actual situation at
the time when you are reading this. Described algorithm probably will not change, but it can be
combined with original PureMVC implementations. If this happens, only requirement will be removal
of "ByConfigName" suffix from these two methods. Name of method registerProxyByConfigName()
probably will not change, since its signature is different from the signature of original PureMVC's
registerProxy() method.

• Let see now what can be done with mediators. There are few roadblocks, but maybe we can do something
about them. In typical PureMVC applications mediators are not usually used as dependencies of other
PureMVC components. After registration, mediators only take notifications from other PureMVC parts.
Also, in a constructor they usually take a parameter which references a visual component (in flex
this is usually some ancestor of the UIComponent class) which can't be configured through an IoC
container (at least I don't know how that can be easily done). Nevertheless, we can still benefit from IoC,
since mediators usually have proxies as dependencies. To support that, there are at least three things
required: support for singletons in PureMVC/Spring Actionscript integration, IoC support for supplying
constructor parameters at runtime (which requires additional IoC feature - the lazy initialization), and
IoC support for custom initialization methods.

Speaking about singletons, they are required if you start to mix PureMVC element configurations. For
example, imagine that we have something like this in a configuration:

<object id="userProxyObject" class="... .UserProxy" scope="prototype"/>

117
Spring Actionscript extensions

<object id="userListMediatorObject" class="...UserListMediator" scope="prototype"


<property name="userProxy" ref="userProxyObject"/>
</object>

Now, if you use the IocFacade to retrieve "userProxyObject" and "userListMediatorObject", then
"userProxyObject" instance and "userListMediatorObject"'s dependency "userProxy" will be two
different instances! This is because every time the IoC container fetches a prototype it always creates
a new instance which usually is not what you want. At this point in PureMVC/Spring Actionscript
development, you can actually use singletons.

Why are dynamic constructor parameters important? Well, as I already said, mediators usually have
visual components as constructor parameters. As visual dependencies can't be configured through Spring
Actionscript, you have to have a way for supplying them at runtime. Since mediators, as they are usually
implemented in typical PureMVC applications, can't be instantiated until the moment when you fetch
them through the IocFacade, the IoC container must support lazy initialization of objects. This means
that objects marked as lazy will not be instantiated at the container startup, their instantiation will be
postponed until you fetch them from the IoC container for the first time. At that moment you could have
an opportunity (if one exists) to supply constructor parameters.

And finally, what about that custom initialization method? Typical PureMVC usage pattern is to
instantiate and use proxy dependencies in the mediator's constructor. If you decide to configure those
proxy dependencies via IoC (like in above configuration code snippet) you will end up with null
references since the IoC container can not inject dependencies before mediator is constructed. So
you will need to refactor dependencies usage in the separate custom initialization method which
should be invoked by IoC container after the mediator was constructed and all its dependencies were
injected. Actually, Spring Actionscript already supports such method by IInitializingObject interface,
but implementing it will unnecessarily add dependency on the Spring Actionscript framework in your
code. It will be much better if you can express in configuration which one of your methods is the
initializing one.

• Lazy initialization is supported with "lazy-init" configuration attribute like in following example:

<object id="userListMediatorObject" class="... .UserListMediator" lazy-init="true

Custom initialization method is supported with "init-method" configuration attribute like in:

<object id="userListMediatorObject" class="... .UserListMediator" lazy-init="true

Dynamic constructor parameters are supported with "p_viewComponent" parameter in IocFacade


registerMediatorByConfigName() method which has following signature:

function registerMediatorByConfigName(p_mediatorName:String, p_viewComponent:Obje

Other IocFacade's features related to mediators mainly have same characteristics as those for
proxies. There only should be noted that magic name for configurable mediator names map is
"mediatorNameMap".

• It should be noted that you don't have to use "lazy-init" and "init-method" features for configuring
Mediators. This is because in PureMVC v2.x, setViewComponent() is added, and now is not required
that you have to supply a view component at construction time. It can be added later. On the other hand,
taking this approach will require some minor changes in implementation of mediators, and its usage in
the context of IoC configured applications.

First, if you want some mediator to be constructed at IoC container startup, its constructor must not be
dependent on a view component. You should factor out that initialization code in some other method,
like in following example:

118
Spring Actionscript extensions

public class MyMediator extends IocMediator {

public function UserFormMediator(p_mediatorName:String = null, p_viewComponent:


super(p_mediatorName, p_viewComponent);

// This code must be factored out in self standing method.


// myViewComponent.addEventListener(MyViewComponent.EVENT_ONE, onEventOne);
// myViewComponent.addEventListener(MyViewComponent.EVENT_TWO, onEventTwo);
// myViewComponent.addEventListener(MyViewComponent.EVENT_THREE, onEventThree
}

public function init():void {


myViewComponent.addEventListener(MyViewComponent.EVENT_ONE, onEventOne);
myViewComponent.addEventListener(MyViewComponent.EVENT_TWO, onEventTwo);
myViewComponent.addEventListener(MyViewComponent.EVENT_THREE, onEventThree);
}

...
}

Now we have init() method which, when invoked, executes initialization code, previously belonging to
the constructor. Only one question remains, when this init() method will be invoked? Well, you have
at least two options. First one is to execute it manually when appropriate, and second one is to execute
it from overridden setViewComponent() method.

If you chose first option you will end up with one more statement during mediator's registration:

public class MyStartupCommand extends IocSimpleCommand {


// ...
// setters and getters omitted.
// ...

override public function execute(p_note:INotification):void {


var app:MyApp = p_note.getBody() as MyApp;
// ...

myMediator.setViewComponent(app.myViewComponent);
myMediator.init();
iocFacade.registerMediatorByConfigName("myMediatorName");

// ...
}
}

If you opt for second option, you will end up adding something like the following in your mediator class:

override public function setViewComponent(p_viewComponent:Object):void {

if (getViewComponent() != null) {
myViewComponent.removeEventListener(MyViewComponent.EVENT_ONE, onEventOne);
myViewComponent.removeEventListener(MyViewComponent.EVENT_TWO, onEventTwo);
myViewComponent.removeEventListener(MyViewComponent.EVENT_THREE, onEventThree
}

119
Spring Actionscript extensions

super.setViewComponent(p_viewComponent);

init();
}

This actually makes sense, since you will typically have to do some preparations every time you change
a view component that mediator mediates.

It should also be noted that whatever approach you choose, it is still compatible with "pure" PureMVC
applications. This means that you can use without problems described usage patterns in all PureMVC
applications. As a side effect, your mediators should be now easier to test because constructor doesn't
use view component any more. In your tests you can add this dependency (probably mocked) through
setViewComponent() only when needed.

• All mentioned things you can see in action in modified Arch101Demo sample.

• Although I said before that support for singletons will be added in third level of integration, I've decided
to add it right now, so that mediator's story can be completed. So, I've added two additional methods
in IocFacade:

function removeProxyByConfigName(p_proxyName:String):void;
function removeMediatorByConfigName(p_mediatorName:String):void;

These allow you to remove cached singleton instances from IoC container. That also required changes
in Spring Actionscript implementation, but not very visible one. If you are interested, I've added
clearObjectFromInternalCache() method in AbstractObjectFactory class.

Here same notes about "ByConfigName" suffix in method names apply as before. If they do not exist
in IIocFacade at the time you are reading this, this only means that you should use standard PureMVC
method names: removeProxy() and removeMediator(). They will function as described here, but you
will not have to worry about that.

Level 3 integration
• As mentioned before, the theme of Level 3 PureMVC/Spring Actionscript integration is support for
PureMVC commands. As it turns out this was very straightforward to implement. But first, let explore
a little how commands are used in typical PureMVC applications.

• Contrary to mediators and proxies, commands are not instantiated by the developer, but rather by the
framework. You just have to pass a class reference to PureMVC and it will create a command instance
when appropriate. PureMVC documentation suggests that commands are created, executed and then
destroyed, meaning that the framework doesn't preserve any references to them after its execution.
I believe that such usage is good practice when you don't have the IoC container at hand. Further,
commands are not used as dependencies of other PureMVC elements, but they usually reference proxies
and sometimes (usually only in a startup command) mediators.

• Now, what can you do with the IoC container? First, if you configure a command as a singleton, the
framework will not have to instantiate them on every execution. Instead, commands can be easily fetched
from the container when needed which can save some time and memory (not really a big issue but
still...). Further, with IoC you can configure dependencies of your commands which will be injected
when the IoC container instantiates them and this is the main point. Additionally, your application's
facade will not have to reference a concrete command classes during command registration. Instead it
can use command's configuration name which is a plain string (usually coded as constant). That way your
commands don't need to be dependent on your concrete proxy or mediator classes and your application
doesn't need anymore be dependant on the concrete command classes. This is all wired together by the
IoC container.

120
Spring Actionscript extensions

• To support described usage I had to replace original PureMVC implementation of IController interface.
This part is not visible to the end programmer. More importantly, the IocFacade got the new
registerCommandByConfigName() method with which you can associate a configuration name used in
the IoC container with a PureMVC notification.

I've also implemented a "magic" command names map with which you can introduce additional
indirection between command configuration names used in code and in IoC configuration. If you decide
to configure it, command names map must have id attribute with value "commandNamesMap". If you
decide at some point that some command is not needed any more you can unregister it as usual by using
the IocFacade's removeCommand() method.

• For working examples of a command usage in combination with the IoC container you should look
at IoC configuration for "commandNamesMap", "startupCommandObject" and "deleteUserCommand"
objects. You should also look at a command registration in the ApplicationFacade class and finally how
the userProxy dependency is now implemented in the DeleteUserCommand class. I hope this will be
enough for you to understand how to use PureMVC/Spring Actionscript integration with PureMVC
commands.

• At the end I want to emphasize the fact that you don't have to use full "Level 2 & 3" integration. If
you find more appropriate, you can just use "consistent ad hoc IoC usage" from "Level 1" integration.
I believe only that part can bring significant benefits to typical PureMVC applications. Despite, you
should give a chance to Level 2 and 3 parts. Try it and decide if this brings any benefit to you.

121
Part III. Appendixes
Appendix A. XML Schema-based
configuration
Introduction
This appendix details the XML Schema-based configuration introduced in Spring Actionscript version 0.8.

The central motivation for using XML Schema based configuration files was to make Spring XML
configuration easier. The 'classic' -based approach is good, but its generic-nature comes with a price in
terms of configuration overhead.

From the Spring Actionscript IoC containers point-of-view, everything is an object. That's great news for
the Spring Actionscript IoC container, because if everything is an object then everything can be treated
in the exact same fashion. The same, however, is not true from a developer's point-of-view. The objects
defined in a Spring Actionscript XML configuration file are not all generic, vanilla objects. Usually, each
object requires some degree of specific configuration.

Spring Actionscript XML Schema-based configuration addresses this issue. The element is still present,
and if you wanted to, you could continue to write the exact same style of Spring Actionscript XML
configuration using only elements. The XML Schema-based configuration does, however, make Spring
Actionscript XML configuration files substantially clearer to read. In addition, it allows you to express
the intent of an object definition.

The key thing to remember is that the new custom tags work best for infrastructure or integration objects:
for example, collections, transactions, integration with 3rd-party frameworks, while the existing object
tags are best suited to application-specific objects, such as DAOs, service layer objects, validators, etc.
The examples included below will hopefully convince you that XML Schema support is a good idea.
Please note the fact that this configuration mechanism is totally customisable and extensible. This means
you can write your own domain-specific configuration tags that would better represent your application's
domain; the process involved in doing so is covered in the appendix entitled Appendix B, Extensible XML
authoring.

XML Schema-based configuration


Referencing the schemas
To use the XML Schema-style, you need to add the following declarations to your XML file.

<?xml version="1.0" encoding="UTF-8">


<objects
xmlns="http://www.springactionscript.org/schema/objects"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springactionscript.org/schema/objects
http://www.springactionscript.org/schema/objects/spring-actionscript-objects-1.0.

<!-- <object/> definitions here -->

</objects>

123
XML Schema-based configuration

Note
The 'xsi:schemaLocation' fragment is not actually required, but can be included to reference a
local copy of a schema (which can be useful during development).

The above Spring Actionscript XML configuration fragment is boilerplate that you can copy and paste
(!) and then plug definitions into like you have always done. The section entitled, "The util schema"
demonstrates how you can start immediately by using some of the more common utility tags. The rest of
this chapter is devoted to showing examples of the Spring Actionscript XML Schema based configuration,
with at least one example for every new tag. The format follows a before and after style, with a before
snippet of XML showing the old (but still 100% legal and supported) style, followed immediately by an
after example showing the equivalent in the new XML Schema-based style.

The util schema


First up is coverage of the util tags. As the name implies, the util tags deal with common, utility
configuration issues, such as configuring collections, referencing constants, and suchlike.

To use the tags in the util schema, you need to have the following preamble at the top of your Spring
Actionscript XML configuration file; the emboldened text in the snippet below references the correct
schema so that the tags in the util namespace are available to you.

<?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:util="http://www.springactionscript.org/schema/util"
xsi:schemaLocation="http://www.springactionscript.org/schema/objects
http://www.springactionscript.org/schema/objects/spring-actionscript-objects-1.0.
http://www.springactionscript.org/schema/objects/spring-actionscript-util-1.0.xsd

<!-- <object/> definitions here -->

</objects>

You also need to register the namespace handler with the application context, like this (invoke this method
before you load the configuration):

applicationContext.addNamespaceHandler(new UtilNamespaceHandler());

Not all util functions have been implemented yet in Spring Actionscript, the ones that are already present
are described below.

<util:constant/>
Before...

<object id="..." class="...">


<property name="version">
<object class="org.springextensions.actionscript.ioc.factory.config.FieldRetrie
<property name="targetClass" value="mx.core.FlexVersion"/>
<property name="staticField" value="CURRENT_VERSION"/>
</object>

124
XML Schema-based configuration

</property>
</object>

The above configuration uses a Spring Actionscript IFactoryObject implementation, the


FieldRetrievingFactoryObject, to set the value of the 'test' property on an object to the value of the
'mx.core.FlexVersion.CURRENT_VERSION' constant. This is all well and good, but it is a tad verbose
and (unnecessarily) exposes Spring Actionscript's internal plumbing to the end user.

The following XML Schema-based version is more concise and clearly expresses the developer's intent
('inject this constant value'), and it just reads better.

<object id="..." class="...">


<property name="test">
<util:constant static-field="mx.core.FlexVersion.CURRENT_VERSION"/>
</property>
</object>

<util:invoke/>
Before...

<object class="org.springextensions.actionscript.ioc.factory.config.MethodInvokingF
<property name="targetClass" value="mx.resources.ResourceManager"/>
<property name="targetMethod" value="getInstance"/>
</object>

After...

<util:invoke target-class="mx.resources.ResourceManager" target-method="getInstance

To pass arguments to the specified method use <arg/> child elements:

<util:invoke target-object="resourceManager" target-method="getString">


<arg value="bundleName"/>
<arg value="resourceName"/>
</util:invoke>

The messaging schema


The messaging schema, to no great surprise, covers all objects that deals with messaging, such as channels,
producers, consumers, etc.

To use the tags in the messaging schema, you need to have the following preamble at the top of your Spring
Actionscript XML configuration file; the emboldened text in the snippet below references the correct
schema so that the tags in the messaging namespace are available to you.

<?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:messaging="http://www.springactionscript.org/schema/messaging"
xsi:schemaLocation="http://www.springactionscript.org/schema/objects
http://www.springactionscript.org/schema/objects/spring-actionscript-objects-1.0.
http://www.springactionscript.org/schema/objects/spring-actionscript-messaging-1.

125
XML Schema-based configuration

<!-- <object/> definitions here -->

</objects>

You also need to register the namespace handler with the application context, like this (invoke this method
before you load the configuration):

applicationContext.addNamespaceHandler(new MessagingNamespaceHandler());

In the following section we will briefly show you what new tags the messaging schema will offer you.

<messaging:channel-set>
To declare a channelset using the messaging schema, add this markup to you XML configuration:

<channel-set clustered="false" initial-destination-id="remote-destination" id="myCh

"remote-destination" is just a generic name in this example, you will need to change this to a destination
id that is suitable for your server environment.

<messaging:channel>
Now to add a channel to our previously declared channelset, you can add the following:

<channel id="myChannel" connect-timeout="50"


failover-uris="http://myfailoverserver.com/flex,http://localhost/flex" request-tim

Then, to add the channel to the channelset, add this attribute to your channelset declaration:

<channel-set clustered="false" initial-destination-id="remote-destination" id="myCh

To add more than one channel, just comma delimit the channel names:

<channel-set clustered="false" initial-destination-id="remote-destination" id="myCh

<messaging:amf-channel>
The amf-channel tag merely adds a few attributes to the regular channel tag that apply to AMF specifically:

<amf-channel id="myChannel" connect-timeout="50"


failover-uris="http://myfailoverserver.com/flex,http://localhost/flex" request-tim
piggybacking-enabled="false"
polling-enabled="true"
polling-interval="200"/>

Other than that there is also the <secure-amf-channel/>, <streaming-amf-channel/


> and the <secure-streaming-amf-channel/>, who map to the SecureAMFChannel,
StreamingAMFChannel and SecureStreamingAMFChannel respectively but who offer no extra
attributes as of yet.

<messaging:abstract-consumer>
Coming soon...

126
XML Schema-based configuration

<messaging:consumer>
Coming soon...

<messaging:multi-topic-consumer>
Coming soon...

<messaging:producer>
Coming soon...

<messaging:multi-topic-producer>
Coming soon...

The RPC schema


Coming soon...

The stage processing schema


The stage processing schema offers markup directly geared towards the GenericStageProcessor class.

To use the tags in the stage processing schema, you need to have the following preamble at the top of
your Spring Actionscript XML configuration file; the emboldened text in the snippet below references the
correct schema so that the tags in the stage processing namespace are available to you.

<?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/stageprocessing "
xsi:schemaLocation="http://www.springactionscript.org/schema/objects
http://www.springactionscript.org/schema/objects/spring-actionscript-objects-1.0.
http://www.springactionscript.org/schema/objects/spring-actionscript-stageprocess

<!-- <object/> definitions here -->

</objects>

You also need to register the namespace handler with the application context, like this (invoke this method
before you load the configuration):

applicationContext.addNamespaceHandler(new StageProcessorNamespaceHandler());

In the following section we will briefly show you what new tags the stage processing schema will offer you.

<si:genericstageprocessor>
Currently there is just one tag in the stage processing namespace, to add a GenericStageProcessor to your
application simply use this markup:

127
XML Schema-based configuration

<si:genericstageprocessor target-object="stageRegistry" target-method="register"


object-selector="registrySelector" id="genericStageProcessor"/

Where the target-object and object-selector attributes are references to existing objects in your application
context.

128
Appendix B. Extensible XML authoring
Introduction
This section is devoted to detailing how you would go about writing your own custom XML object
definition parsers and integrating such parsers into the Spring Actionscript IoC container.

To facilitate the authoring of configuration files using a schema-aware XML editor, Spring Actionscript's
extensible XML configuration mechanism is based on XML Schema. If you are not familiar with Spring
Actionscript's current XML configuration extensions that come with the standard Spring Actionscript
distribution, please first read the appendix entitled "Appendix A, XML Schema-based configuration."

Creating new XML configuration extensions can be done by following these (relatively) simple steps:

• Authoring an XML schema to describe your custom element(s).

• Coding a custom INamespaceHandler implementation (this is an easy step, don't worry).

• Coding one or more IObjectDefinitionParser implementations (this is where the real work is done).

• Registering the above artifacts with Spring Actionscript (this too is an easy step).

What follows is a description of each of these steps. For the example, we will create an XML extension
(a custom XML element) that allows us to configure objects of the type DateFormatter (from the Flex
mx.formatters.DateFormatter package) in an easy manner. When we are done, we will be able to define
object definitions of type DateFormatter like this:

<mydatens:ddateformatter id="dateFormat"
format-string="MM/DD/YYYY"/>

(Don't worry about the fact that this example is very simple; much more detailed examples follow
afterwards. The intent in this first simple example is to walk you through the basic steps involved.)

Authoring the schema


Creating an XML configuration extension for use with Spring Actionscript's IoC container starts with
authoring an XML Schema to describe the extension. What follows is the schema we'll use to configure
Date objects.

<xsd:schema xmlns="http://www.springactionscript.org/schema/mydatens"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.springactionscript.org/schema/mydatens"
elementFormDefault="qualified">

<xsd:import namespace="http://www.springactionscript.org/schema/objects"/>

<xsd:element name="dateformatter">
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="objects:objectType">
<xsd:attribute name="format-string" type="xsd:string" use="required"/>
</xsd:extension>

129
Extensible XML authoring

</xsd:complexContent>
</xsd:complexType>
</xsd:element>

</xsd:schema>

(The emphasized line contains an extension base for all tags that will are an object (meaning they have an id
attribute, class attribute, etc). We are able to use this attribute because we imported the Spring Actionscript-
provided 'objects' namespace.)

The above schema will be used to configure Date objects, directly in an XML application context file
using the <mydatens:dateformatter/> element.

<mydatens:dateformatter id="dateFormatter"
format-string="MM/DD/YYYY"/>

Note that after we've created the infrastructure classes, the above snippet of XML will essentially be exactly
the same as the following XML snippet. In other words, we're just creating an object in the container,
identified by the name 'dateFormat' of type DateFormatter, with a couple of properties set.

<object id="dateFormatter" class="mx.formatters.DateFormatter">


<property name="formatString" value="MM/DD/YYYY"/>
</object>

Note
The schema-based approach to creating configuration format allows for tight integration with
an IDE that has a schema-aware XML editor. Using a properly authored schema, you can use
auto completion to have a user choose between several configuration options defined in the
enumeration.

Coding an INamespaceHandler implementation


In addition to the schema, we need an INamespaceHandler that will parse all elements of this specific
namespace Spring Actionscript encounters while parsing configuration files. The INamespaceHandler
should in our case take care of the parsing of the mydatens:dateformatter element.

The INamespaceHandler interface is pretty simple in that it features just two methods:

public interface INamespaceHandler {

/**
* Return the namespace supported by this namespace handler.
*/
function getNamespace():Namespace;

/**
* Parses the given node and returns the resulting object definition.
*
* @param node the xml node to parse
* @param context the root xml parser
*/
function parse(node:XML, context:XMLObjectDefinitionsParser):IObjectDefinition;

130
Extensible XML authoring

Although it is perfectly possible to code your own INamespaceHandler for the entire namespace (and
hence provide code that parses each and every element in the namespace), it is often the case that each top-
level XML element in a Spring Actionscript XML configuration file results in a single object definition
(as in our case, where a single <mydatens:dateformatter/> element results in a single DateFormatter object
definition). Spring Actionscript features a number of convenience classes that support this scenario. In this
example, we'll make use of the NamespaceHandlerSupport class:

package org.springextensions.actionscript.ioc.factory.xml {

public class MyNamespaceHandler extends NamespaceHandlerSupport {

public function MyNamespaceHandler() {


super(new Namespace("http://www.springactionscript.org/schema/mydatens"));

registerObjectDefinitionParser("dateformatter", new DateFormatterNodeParser());


}

}
}

The observant reader will notice that there isn't actually a whole lot of parsing logic in this class.
Indeed... the NamespaceHandlerSupport class has a built in notion of delegation. It supports the registration
of any number of IObjectDefinitionParser instances, to which it will delegate to when it needs to
parse an element in it's namespace. This clean separation of concerns allows an INamespaceHandler
to handle the orchestration of the parsing of all of the custom elements in it's namespace, while
delegating to IObjectDefinitionParsers to do the grunt work of the XML parsing; this means that each
IObjectDefinitionParser will contain just the logic for parsing a single custom element, as we can see in
the next step.

Coding an IObjectDefinitionParser
implementation
An IObjectDefinitionParser will be used if the INamespaceHandler encounters an XML element of the
type that has been mapped to the specific object definition parser (which is 'dateformatter' in this case).
In other words, the IObjectDefinitionParser is responsible for parsing one distinct top-level XML element
defined in the schema. In the parser, we'll have access to the XML element (and thus it's sub elements too)
so that we can parse our custom XML content, as can be seen in the following example:

package org.springextensions.actionscript.ioc.factory.xml {
import mx.formatters.DateFormatter;

import org.springextensions.actionscript.ioc.IObjectDefinition;
import org.springextensions.actionscript.ioc.factory.support.ObjectDefinitionBuild
import org.springextensions.actionscript.ioc.factory.xml.parser.support.ParsingUti
import org.springextensions.actionscript.ioc.factory.xml.parser.support.XMLObjectD

public class DateFormatterNodeParser extends AbstractObjectDefinitionParser {

public function DateFormatterNodeParser() {


super();
}

131
Extensible XML authoring

override protected function parseInternal(node:XML, context:XMLObjectDefinitionsP


var result:ObjectDefinitionBuilder = ObjectDefinitionBuilder.objectDefinitionFor

ParsingUtils.mapProperties(result.objectDefinition, node, "format-string");

return result.objectDefinition;

}
}

1. We use the SpringActionscript-provided AbstractObjectDefinitionParser to handle a lot of the basic


grunt work of creating a single IObjectDefinition.

2. We supply the AbstractObjectDefinitionParser superclass with the type that our single
IObjectDefinition will represent.

3. We use the SpringActionscript-provided ParsingUtils to automatically map XML attributes to object


properties.

In this simple case, this is all that we need to do. The creation of our single IObjectDefinition is handled
by the AbstractObjectDefinitionParser superclass, as is the extraction and setting of the object definition's
unique identifier.

Registering the handler


The coding is finished! All that remains to be done is to somehow make the Spring Actionscript XML
parsing infrastructure aware of our custom element. For this particular task you can simply call the
addNamespaceHandler() method on the application context instance, passing it an instance of your newly
created INamespaceHandler.

applicationContext.addNamespaceHandler(new MyNamespaceHandler());

And that's it, if you make sure you've declared your own namespace properly in the XML configuration,
from now on the Spring Actionscript container will be able to parse and create your object definitions.

Note
Obviously you must invoke the addNameSpaceHandler() method before you invoke the load()
method.

Code generator
Spring Actionscript offers a small AIR application (whose source can also be found in the 'samples'
section of the SVN repository). This application can load and analyze a .swc file, extract class
information and based on this generate a namespace, a NamespaceHandlerSupport subclass, a list of
IObjectDefinitionsParsers and a schema file.

Obviously this code generator will not be suitable for more complex implementations, but it can at least
provide you with some boiler plate code and give you a better insight in the workings and dependencies
of the different classes.

132
Extensible XML authoring

You can download the AIR installer by .

133
Appendix C. Forcing Actionscript class
inclusion
Introduction
Once you move the configuration of your objects out of your source code you will notice a very common
problem. Because there is not always a direct reference to certain classes inside your source code these
classes will not end up being compiled into the resulting .swf file. Then, while running your application,
you will encounter the dreaded "Error: A class with the name 'XXXXX' could not be found." message.

There is a variety of ways to force the compiler to include certain classes, in this section we will look at
most of them.

Adding an anonymous code block


Place this anywhere in your code, at the top of your application source for instance:

{
Myclass1, Myclass2
}

Declaring a list of variables


Another way is to just declare a whole list of dummy variables with the required types:

private var _dummy1:Myclass1;


private var _dummy2:Myclass2;

or just one array of class declarations:

private var _includeClass:Array = [Myclass1,Myclass2];

Using the Frame metadata


There is an undocumented piece of metadata that will force the compiler to include a second or third class
to an existing class source.

package com.myclasses
{
[Frame(extraClass="com.myclasses.Myclass1")]
[Frame(extraClass="com.myclasses.Myclass2")]
public class MyMainClass
{
}
}

After that you only need to declare one variable of type MyMainClass in your source code.

Using a resource bundle


Its possible to create a .properties file that contains all the class references you. Create a file in your project
called classreferences.properties and add your classes like this:

134
Forcing Actionscript class inclusion

Class1 = ClassReference("com.myclasses.Myclass1")
Class2 = ClassReference("com.myclasses.Myclass2")

Then in your application source code add a reference to the resource like this:

[ResourceBundle("classreferences")]
private var _classReferences:ResourceBundle;

Using an ANT task as a prebuilder to generate a


compiler config file
The last solution is a little more involved but can eventually automate the whole task of class inclusion, in
this section we will explain step-by-step how to configure Flexbuilder to run a prebuilder.

Step 1 - Add a compiler switch to your project


Right click on your project in Eclipse/Flexbuilder and choose the menu item 'Properties', in the following
popup add the compiler switch like this:

Step 2 – Create an XSLT ANT Task


Step 2 – Create an XSLT ANT Task In your project root (NOT your 'src' directory) create an XML file,
call it 'springasprebuild.xml' (the same filename you used in the compiler switch), and in this file add the
following code:

<!--
======================================================================
Nov 17, 2008 4:33:15 PM
project SpringAS Pre build
description Extracts all the class paths from a Spring Actionscript
configuration file and dumps them into
a config file that can be added with a compiler
switch (i.e. -load-config+=custom.config)
Roland Zwaga
====================================================================== -
->
<project name="project" default="default">
<description>
Extracts all the class paths from a Spring Actionscript configuration file and
dumps them in a config file that can be added with a compiler switch
(i.e. -load-config+=custom.config)
</description>
<!--
=================================
target: default
=================================
-->
<target name="default" description="description">
<xslt in="src/application-context.xml" out="src/springas.config"
style="xslt/springasconfig.xsl" reloadstylesheet="false"></xslt>
</target>
</project>

135
Forcing Actionscript class inclusion

Take notice of XSLT element in the code, it has4 attributes:

• in – this is the path to your Spring Actionscript configuration file

• out – this is the path to the output file for the XSLT task, this is the file that was added as a compiler
switch in the previous step.

• style – This is the actual stylesheet that contains the necessary code to generate the output.

• reloadstylesheet – only set this to true when you have made changes to the XSLT, otherwise leave it
set to false.

Step 3 – Add the XSLT to your project


Create a new directory in your project root and call it 'xslt', create a new file in this directory called
'springasconfig.xsl'. Add the following code to the file:

<?xml version="1.0" encoding="UTF-8"?>


<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:springas="http://www.springactionscript.org/schema/objects"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springactionscript.org/schema/objects
http://www.springactionscript.org/schema/objects/spring-actionscrip
exclude-result-prefixes="xsi springas">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="restriction" match="//springas:object" use="@class" />
<xsl:key name="proprestriction" match="//springas:property"
use="@value" />
<xsl:key name="valrestriction" match="//springas:value" use="." />
<xsl:template match="/">
<flex-config>
<includes append="true">
<xsl:for-each
select="//springas:object[count(.|key('restriction',@class)[1]) = 1]">
<xsl:sort select="@class"/>
<xsl:if test="@class!=''">
<symbol>
<xsl:value-of select="@class"/>
</symbol>
</xsl:if>
</xsl:for-each>
<xsl:for-each
select="//springas:property[count(.|key('proprestriction',@value)[1]) = 1]"
<xsl:sort select="@value"/>
<xsl:if test="@type='Class'">
<symbol>
<xsl:value-of select="@value"/>
</symbol>
</xsl:if>
</xsl:for-each>
<xsl:for-each
select="//springas:value[count(.|key('valrestriction',.)[1]) = 1]">
<xsl:sort select="."/>
<xsl:if test="@type='Class'">

136
Forcing Actionscript class inclusion

<symbol>
<xsl:value-of select="."/>
</symbol>
</xsl:if>
</xsl:for-each>
</includes>
</flex-config>
</xsl:template>
</xsl:stylesheet>

Step 4 – Add the ANT task as a builder


In the last step you add the ANT task as a builder to your project, do this by right clicking on your project,
Choose 'Properties' and select the tab called 'Builders':

Click on 'New' and choose 'ANT Builder' and click 'OK', this dialog should appear:

Give the builder a logical name, something like 'Spring AS Prebuilder', afterwards click 'Browse
workspace' beneath the 'Buildfile' input field, in the following dialog choose the Buildfile from the root of
your current project. In case of this example its called 'springasprebuild.xml':

Then click 'OK' to return to the builder list. The builder you just added is in the wrong order still though.
We want it to be the first builder to be executed in the build process, so select the ‘Spring AS Prebuilder’
in the list and click on 'Up', after this the list will look like this:

Click 'OK' and your project is configured!. To test whether everything is in working order, build your
project. If all went according to plan then in the root of your source folder a new file has been created
called 'springas.config'. The contents of this file will look something like this:

<?xml version="1.0" encoding="UTF-8"?>


<flex-config>
<includes append="true">
<symbol>mx.messaging.channels.AMFChannel</symbol>
<symbol>mx.messaging.ChannelSet</symbol>
<symbol>mx.rpc.remoting.mxml.RemoteObject</symbol>
</includes>
</flex-config>

And that's it, once in place this will take care of filtering out the classes from your Spring Actionscript
configuration file.

Well, at least in most cases :)

Using Maven
If you use Maven as a build system for your application, Spring Actionscript also offers a mojo that will
generate a flex compiler config file based on an application context. You can download the mojo .

137
Forcing Actionscript class inclusion

Download the zip file and open the directory it is contained in and run "mvn install" on the mojo to get
it into your local repository.

Then use it your build like this:

...
<!-- set up properties to make it easy for both plugins (the prebuild and the maven
<properties>
<generatedCompilerConfigName>spring-as-includes.config</generatedCompilerCo
<generatedCompilerConfigDir>${project.build.sourceDirectory}</generatedComp
</properties>
<build>
...
<plugins>
<plugin>
<groupId>org.springextensions.actionscript</groupId>
<artifactId>prebuild-mojo</artifactId>
<version>0.1-SNAPSHOT</version>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>generate-compiler-config</goal>
</goals>
</execution>
</executions>
<configuration>
<springActionscriptContextFiles>
<param>${basedir}/src/main/flex/YOUR-CONTEXT-FILE.xml</para
</springActionscriptContextFiles>
<outputDirectory>${generatedCompilerConfigDir}</outputDirectory
<generatedConfigFileName>${generatedCompilerConfigName}</genera
</configuration>
</plugin>
<plugin>
<groupId>org.sonatype.flexmojos</groupId>
<artifactId>flexmojos-maven-plugin</artifactId>
<version>3.6-SNAPSHOT</version>
<configuration>
...
<configFiles>
<file>${generatedCompilerConfigDir}/${generatedCompilerConfi
</configFiles>
...
</configuration>

</plugin>
</plugins>
</build>
...

And that's all there is to it!

138
Part IV. Reference
Chapter 9. Configuration reference
This section has been generated from the schema file 'spring-
actionscript-objects-1.0.xsd'

General description
<literallayout> Spring ActionScript Framework 1.0 Schema Schema Authors: Ryan Gardner,
Erik Westra, Christophe Herreman, Roland Zwaga This defines a simple and consistent way
of creating a namespace of ActionScript objects, managed by a Spring ActionScript IoC
Container, read by XmlObjectDefinitionParser. Every attempt has been made to make this scheme
comprehensive and correct. Configuring your XML context-configuration like this: <?xml version="1.0"
encoding="UTF-8" standalone="no"?> <objects xmlns="http://www.springactionscript.org/schema/
objects" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://
www.springactionscript.org/schema/objects http://www.springactionscript.org/schema/objects/spring-
actionscript-objects-1.0.xsd"> <!-- object and template definitions --> </objects> Will enable most
schema-aware tools to automatically retrieve the schema and provide on-the-fly validation and code-
completion as you create your context definition. The main goal of this schema is to provide easy assistance
in creating the file, and basic validation of the syntax. Please feel free to provide updates to the Spring
ActionScript team if you see any areas to improve. </literallayout>

Overview

• arg

• array

• array-collection

• constructor-arg

• dictionary

• entry

• import

• interface

• key

• method-invocation

• object

• objects

• param

• property

• property

140
Configuration reference

• ref

• template

• value

• vector

<section>
<title>
<programlisting><arg/></programlisting>
</title>
<literallayout>Defines a method argument.</literallayout>
<itemizedlist>
<title>Attributes</title>
<listitem>value
<remark>
<literallayout>A literal value for the argument.</literallayout>
</remark>
</listitem>
<listitem>ref
<remark>
<literallayout>A reference to another object defined in the container.</literallayout>
</remark>
</listitem>
<listitem>template
<remark>
<literallayout>The name of a template which should be used as the value of the specified argument. When
defined as an attribute no parameters can be passed to the template, so no placeholder substitution will
occur. Use a child template element instead if parameters are needed.</literallayout>
</remark>
</listitem>
</itemizedlist>
</section>
<section>
<title>
<programlisting><array/></programlisting>
</title>
<literallayout>The array contains a list of the following possible values, these types can be mixed.</
literallayout>
</section>
<section>
<title>
<programlisting><array-collection/></programlisting>
</title>
<literallayout>The array-collection contains a list of the following possible values, these types can be
mixed</literallayout>
</section>
<section>
<title>
<programlisting><constructor-arg/></programlisting>
</title>
<literallayout>Constructor arguments. You can pass in a comma-delimited set of values, or a more
complex value.</literallayout>
<itemizedlist>

141
Configuration reference

<title>Attributes</title>
<listitem>value
<remark>
<literallayout>A literal value for this particular argument. This can be a comma-delimited set of values</
literallayout>
</remark>
</listitem>
<listitem>ref
<remark>
<literallayout>A reference to an object defined in the container.</literallayout>
</remark>
</listitem>
<listitem>template
<remark>
<literallayout>The name of a template which should be used to instantiate this specific argument. When
defined as an attribute no parameters can be passed to the template, so no placeholder substitution will
occur. Use a child template elementinstead if parameters are needed.</literallayout>
</remark>
</listitem>
<listitem>type
<remark>
<literallayout> Defines an optional type for the constructor argument, the value of the value attribute will
be cast to this type at runtime. </literallayout>
</remark>
</listitem>
</itemizedlist>
</section>
<section>
<title>
<programlisting><dictionary/></programlisting>
</title>
<literallayout>A dictionary contains a list properties specified like this: <property name="level">
<dictionary> <entry> <key>a key</key> <value>a</value> </entry> <entry> <key>another key</key>
<value>1</value> </entry> <entry> <key>true</key> <value> <array> <value>b</value> <value>c</
value> </array> </value> </entry> </dictionary> </property> </literallayout>
<para> The following elements occur in dictionary: </para>
<simplelist>
<member>
<link>entry</link>
</member>
</simplelist>
</section>
<section>
<title>
<programlisting><entry/></programlisting>
</title>
<literallayout>Defines an entry that will be added to a dictionary instance.</literallayout>
<itemizedlist>
<title>Attributes</title>
<listitem>key
<remark>
<literallayout>A literal key name for the specified entry.</literallayout>
</remark>
</listitem>

142
Configuration reference

<listitem>value
<remark>
<literallayout>A literal value for the specified entry.</literallayout>
</remark>
</listitem>
</itemizedlist>
<para> The following elements occur in entry: </para>
<simplelist>
<member>
<link>key</link>
</member>
<member>
<link>value</link>
</member>
</simplelist>
</section>
<section>
<title>
<programlisting><import/></programlisting>
</title>
<literallayout>Imports an external configuration file, this way its possible to split up a configuration into
multiple files to keep a better overview or to keep different version of the configuration across different
servers.</literallayout>
<itemizedlist>
<title>Attributes</title>
<listitem>file (required)
<remark>
<literallayout>A valid URI for the specified file. For a flex project this can be a relative URI, when
used in an AIR application make sure to add a fully qualified local URI such as file:///subconfig.xml</
literallayout>
</remark>
</listitem>
</itemizedlist>
</section>
<section>
<title>
<programlisting><interface/></programlisting>
</title>
<literallayout>The Interface type defines properties and methods for objects that implement the specified
interface.</literallayout>
<itemizedlist>
<title>Attributes</title>
<listitem>class
<remark>
<literallayout>The fully qualified classname for the specified interface. This class needs to be known at
compile-time otherwise a runtime error will occur.</literallayout>
</remark>
</listitem>
<listitem>init-method
<remark>
<literallayout>The name of a generic initialization method which will be called directly after instantiation
and property injection.</literallayout>
</remark>
</listitem>

143
Configuration reference

</itemizedlist>
<para> The following elements occur in interface: </para>
<simplelist></simplelist>
</section>
<section>
<title>
<programlisting><key/></programlisting>
</title>
<literallayout>Defines a key that will be used for a dictionary entry.</literallayout>
<itemizedlist>
<title>Attributes</title>
<listitem>type
<remark></remark>
</listitem>
</itemizedlist>
<para> The following elements occur in key: </para>
<simplelist>
<member>
<link>object</link>
</member>
<member>
<link>array</link>
</member>
<member>
<link>array-collection</link>
</member>
<member>
<link>dictionary</link>
</member>
<member>
<link>ref</link>
</member>
</simplelist>
</section>
<section>
<title>
<programlisting><method-invocation/></programlisting>
</title>
<literallayout>Defines a method and optional method arguments. After instantiation of the object the
specified method will be invoked with the specified arguments. No compile checks are possible for this
definition, so if the method does not exist on the object this will result in a runtime error.</literallayout>
<itemizedlist>
<title>Attributes</title>
<listitem>name (required)
<remark>
<literallayout>The name of the method.</literallayout>
</remark>
</listitem>
</itemizedlist>
<para> The following elements occur in method-invocation: </para>
<simplelist>
<member>
<link>arg</link>
</member>

144
Configuration reference

</simplelist>
</section>
<section>
<title>
<programlisting><object/></programlisting>
</title>
<literallayout>The Object type defines the basic Object that is configured by the IoC container.</
literallayout>
<itemizedlist>
<title>Attributes</title>
<listitem>class
<remark>
<literallayout>The fully qualified classname for the specified object. This class needs to be known at
compile-time otherwise a runtime error will occur.</literallayout>
</remark>
</listitem>
<listitem>id
<remark>
<literallayout>A unique id. This id can be used to retrieve an object by calling the getObject method on
the applicationcontext.</literallayout>
</remark>
</listitem>
<listitem>factory-method
<remark>
<literallayout>Optional method that will be called instead of the constructor.</literallayout>
</remark>
</listitem>
<listitem>factory-object
<remark>
<literallayout>Optional name of a factory object responsible for the creation of the object.</literallayout>
</remark>
</listitem>
<listitem>scope =enumeration(prototype,singleton)
<remark>
<literallayout>When an object is a singleton, only one shared instance of the object will be managed, and
all requests for objects with an id or ids matching that object definition will result in that one specific bean
instance being returned by the Spring container. The non-singleton, prototype scope of object deployment
results in the creation of a new object instance every time a request for that specific object is made (that
is, it is injected into another object or it is requested via a programmatic getObject() method call on the
container). As a rule of thumb, you should use the prototype scope for all objects that are stateful, while
the singleton scope should be used for stateless objects.</literallayout>
</remark>
</listitem>
<listitem>lazy-init
<remark>
<literallayout>By default objects marked as a singleton will be constructed immediately after the container
has finished initializing. When lazy-init is set to true though, instantation will be deferred until the first
time that the getObject method is called for the specified singleton.</literallayout>
</remark>
</listitem>
<listitem>init-method
<remark>
<literallayout>The name of a generic initialization method which will be called directly after instantation
and property injection.</literallayout>

145
Configuration reference

</remark>
</listitem>
<listitem>destroy-method
<remark>
<literallayout>The name of a generic destroy method which will be called when the application context
is disposed.</literallayout>
</remark>
</listitem>
<listitem>singleton
<remark>
<literallayout>When set to true, this property determines that the getObject method will always return a
reference to the same instance of the specified object. When set to false, the getObject method will always
return a new instance.</literallayout>
</remark>
</listitem>
<listitem>template
<remark>
<literallayout>The id of a template defined in the current container.</literallayout>
</remark>
</listitem>
<listitem>abstract
<remark>
<literallayout>When set to true this property determines that the specified object cannot be directly
instantiated on its own since it is incomplete. When a definition is considered abstract like this (explicitly or
implicitly), it's usable just as a pure template or abstract object definition that will serve as parent definition
for child definitions.</literallayout>
</remark>
</listitem>
<listitem>parent
<remark>
<literallayout>The id of another object defined in the current container. A child object definition will use
the object class from the parent definition if none is specified, but can also override it. In the latter case,
the child object class must be compatible with the parent, i.e. it must accept the parent's property values. A
child object definition will inherit constructor argument values, property values and method overrides from
the parent, with the option to add new values. If init method, destroy method and/or static factory method
are specified, they will override the corresponding parent settings. The remaining settings will always be
taken from the child definition: depends-on, dependency check, singleton, lazy-init.</literallayout>
</remark>
</listitem>
<listitem>depends-on
<remark>
<literallayout>For the relatively infrequent situations where dependencies between objects are less direct
(for example, when a static initializer in a class needs to be triggered), the depends-on element may be used
to explicitly force one or more objects to be initialized before the object using this element is initialized.</
literallayout>
</remark>
</listitem>
<listitem>autowire-candidate
<remark>
<literallayout>True if this object may be used as an autowiring candidate when another object is autowired
byType</literallayout>
</remark>
</listitem>
<listitem>primary

146
Configuration reference

<remark>
<literallayout>True if more than one object of the same type exists in the configuration and the current
object needs to be the autowire candidate.</literallayout>
</remark>
</listitem>
<listitem>skip-postprocessors
<remark>
<literallayout>Determines whether the object factory will send the created object through its list of
IObjectProcessors.</literallayout>
</remark>
</listitem>
<listitem>skip-metadata
<remark>
<literallayout>Determines whether the autowire processor will examine the class metadata.</
literallayout>
</remark>
</listitem>
<listitem>autowire =enumeration(autodetect,byName,byType,constructor,no)
<remark>
<literallayout>Defines the autowiring strategy to be used for the current object, default is 'no'.</
literallayout>
</remark>
</listitem>
<listitem>dependency-check =enumeration(all,none,objects,simple)
<remark>
<literallayout>Defines the dependency check strategy to be used after autowired properties are set for the
current object, default is 'none'.</literallayout>
</remark>
</listitem>
</itemizedlist>
<para> The following elements occur in object: </para>
<simplelist></simplelist>
</section>
<section>
<title>
<programlisting><param/></programlisting>
</title>
<literallayout>Template parameters have a name and a value. Currently only string replacement for
parameter values is allowed.</literallayout>
</section>
<section>
<title>
<programlisting><property/></programlisting>
</title>
<literallayout>Can be used to load external properties from a file. This is similar to how Ant loads external
properties. <property file="strings.properties" /> the property file looks like: s1=First string s2=Second
string Note: the path to the property file is relative to the path of the application context xml file. Note:
on some servers, the "properties" extension might be blocked. You can either allow the extension in
the server configuration or add an extra "txt" (or other) prefix that is allowed to be served: <property
file="strings.properties.txt" /> The properties loader will prevent caching of the properties by default,
to turn this behavior off set the prevent-cache attribute to false: <property file="strings.properties.txt"
prevent-cache="false"/> By default the properties loader will throw an error if a properties file could
not be loaded, to ignore the error and resume loading set the required attribute to false: <property
file="strings.properties.txt" required="false"/> it is also possible to directly define properties using this

147
Configuration reference

element. In this case omit the file attribute and add the name and value as attributes, like this: <property
name="s1" value="First string"/> <property name="s2" value="Second string"/> The file attribute will
take precedence over the name and value attributes. </literallayout>
<itemizedlist>
<title>Attributes</title>
<listitem>file
<remark>
<literallayout>A valid URI for the specified properties file. For a flex project this can be a relative
URI, when used in an AIR application make sure to add a fully qualified local URI such as file:///
subconfig.xml</literallayout>
</remark>
</listitem>
<listitem>prevent-cache
<remark>
<literallayout>If true the properties loader will make sure no cached copy of the file will be loaded</
literallayout>
</remark>
</listitem>
<listitem>required
<remark>
<literallayout>If true the properties loader will throw an error when the file could not be loaded</
literallayout>
</remark>
</listitem>
<listitem>name
<remark>
<literallayout>The name of the property</literallayout>
</remark>
</listitem>
<listitem>value
<remark>
<literallayout>The value of the property</literallayout>
</remark>
</listitem>
</itemizedlist>
</section>
<section>
<title>
<programlisting><property/></programlisting>
</title>
<literallayout>Defines the value of a property on an object.</literallayout>
<itemizedlist>
<title>Attributes</title>
<listitem>name
<remark>
<literallayout>The name of the specified property.</literallayout>
</remark>
</listitem>
<listitem>value
<remark>
<literallayout>A literal value for the property.</literallayout>
</remark>
</listitem>
<listitem>type

148
Configuration reference

<remark>
<literallayout>Defines an optional type for the property, the value of the value attribute will be cast to this
type at runtime.</literallayout>
</remark>
</listitem>
<listitem>ref
<remark>
<literallayout>A reference to another object defined in the container.</literallayout>
</remark>
</listitem>
<listitem>template
<remark>
<literallayout>The name of a template which should be used to instantiate this specific property. When
defined as an attribute no parameters can be passed to the template, so no placeholder substitution will
occur. Use a child template element instead if parameters are needed.</literallayout>
</remark>
</listitem>
</itemizedlist>
</section>
<section>
<title>
<programlisting><template/></programlisting>
</title>
<literallayout>A template is used to assist in creation of other objects. It can define a number
of properties that will be injected by the same values and instances for every object based on
this template. To use a template, you can specify variables in braces (placeholders). Here is
an example: <template id="remoteObject"> <object class="mx.rpc.remoting.mxml.RemoteObject">
<property name="destination" value="GenericDestination"/> <property name="endpoint"
ref="remoteGateway"/> <property name="source" value="ApplicationDomain.Services.
${serviceClass}"/> </object> </template> and used like: <object id="serviceLocator"
class="org.springextensions.actionscript.cairngorm.CairngormServiceLocator" factory-
method="getInstance"> <property name="assetService" template="remoteObject"> <param
name="serviceClass" value="AssetService"/> </property> <property name="packageService"
template="remoteObject"> <param name="serviceClass" value="PackageService"/> </property>
<property name="userService" template="remoteObject"> <param name="serviceClass"
value="UserService"/> </property> </object> </literallayout>
<itemizedlist>
<title>Attributes</title>
<listitem>id
<remark>
<literallayout>A unique identifier for the specified template.</literallayout>
</remark>
</listitem>
</itemizedlist>
<para> The following elements occur in template: </para>
<simplelist>
<member>
<link>object</link>
</member>
</simplelist>
</section>
<section>
<title>
<programlisting><value/></programlisting>

149
Configuration reference

</title>
<literallayout>Defines a value that will be used for a dictionary entry.</literallayout>
<itemizedlist>
<title>Attributes</title>
<listitem>type
<remark></remark>
</listitem>
</itemizedlist>
<para> The following elements occur in value: </para>
<simplelist>
<member>
<link>object</link>
</member>
<member>
<link>array</link>
</member>
<member>
<link>array-collection</link>
</member>
<member>
<link>dictionary</link>
</member>
<member>
<link>ref</link>
</member>
</simplelist>
</section>
<section>
<title>
<programlisting><vector/></programlisting>
</title>
<literallayout>The vector contains a list of the following possible values, these types can be mixed. The
eventual resolved objects need to be of the same Class as the type attribute indicates.</literallayout>
<itemizedlist>
<title>Attributes</title>
<listitem>type (required)
<remark></remark>
</listitem>
</itemizedlist>
<para> The following elements occur in vector: </para>
<simplelist>
<member>
<link>value</link>
</member>
<member>
<link>ref</link>
</member>
<member>
<link>object</link>
</member>
</simplelist>
</section>

150
Spring actionscript Glossary
This is a list of terms used throughout the Spring Actionscript documentation.

C
Cairngorm Cairngorm is the lightweight micro-architecture for Rich Internet
Applications built in Flex or AIR. A collaboration of recognized
design patterns, Cairngorm exemplifies and encourages best-practices
for RIA development advocated by Adobe Consulting, encourages
best-practice leverage of the underlying Flex framework, while
making it easier for medium to large teams of software engineers
deliver medium to large scale, mission-critical Rich Internet
Applications.

D
DI See Dependency injection.

Dependency injection Dependency Injection (DI) in computer programming refers to the


process of supplying an external dependency to a software component.
It is a specific form of inversion of control where the concern being
inverted is the process of obtaining the needed dependency. The
term was first coined by Martin Fowler to more clearly describe the
mechanism.
See Also Inversion of Control.

E
Extensible Markup Language XML (Extensible Markup Language) is a general-purpose
specification for creating custom markup languages.
See Also Extensible Markup Language.

I
IoC See Inversion of Control.

Inversion of Control Inversion of Control, or IoC, is an abstract principle describing


an aspect of some software architecture designs in which the flow
of control of a system is inverted in comparison to the traditional
architecture of software libraries.
See Also Dependency injection.

Integrated development An integrated development environment (IDE) also known as


environment integrated design environment or integrated debugging environment
is a software application that provides comprehensive facilities to
computer programmers for software development.

151
P
PureMVC PureMVC is a lightweight framework for creating applications based
upon the classic Model, View and Controller concept. Based upon
proven design patterns, this free, open source framework which
was originally implemented in the ActionScript 3 language for use
with Adobe Flex, Flash and AIR, is now being ported to all major
development platforms.

X
XML See Extensible Markup Language.

152

Вам также может понравиться