24 February 2008
Some knowledge of Flex and Spring.
Flex is rapidly becoming the preferred technology for building groundbreaking internet applications delivered in the browser and on the desktop (using the AIR runtime). For several years, Spring has been one of the most popular frameworks for building the Java back-end of internet applications. In this article, we describe how to use BlazeDS Remoting to seamlessly integrate the two technologies and build state-of-the-art internet applications made of a Flex front-end and a Spring back-end.
Whether you are a Flex developer with limited knowledge of Spring, or a Spring developer with limited knowledge of Flex, you can benefit from the powerful integration of these products. This section describes how BlazeDS enables a tight integration between Flex and Spring, and provides background information on the technologies at play.
Spring is one of the most popular Java frameworks. The foundation of the Spring framework is a lightweight component container that implements the Inversion of Control (IoC) pattern.
Using an IoC container, components don't instantiate or even look up their dependencies (the objects they work with). The container is responsible for injecting those dependencies when it creates the components (hence the term "Dependency Injection" also used to describe this pattern).
The result is looser coupling between components. The Spring IoC container has proven to be a solid foundation for building robust enterprise applications. The components managed by the Spring IoC container are called Spring beans.
The Spring framework includes several other modules in addition to its core IoC container. These modules are not covered in this document even though we will be using the Spring JDBC abstraction framework in the second sample application below. More information on the Spring framework can be found at http://www.springframework.org.
Flex is an environment for building Rich Internet Applications. The Flex programming model is made of:
The Flex source code (.mxml and .as files) is compiled into Flash bytecode (.swf) that is executed at the client-side by the Flash virtual machine using a Just-In-Time compiler.
The Flex SDK is an open source project. It includes the Flex component library, the compiler, the debugger, and the documentation. A complete discussion of Flex is beyond the scope of this document. You can find more information and download the Flex SDK at http://opensource.adobe.com.
BlazeDS is a set of data services that give your Flex applications additional options for data connectivity. Without BlazeDS (or, without deploying any Flex-specific component at the server-side), Flex applications can access back-end data using either the HTTPService or the WebService:
BlazeDS adds the following services:
BlazeDS is deployed as a set of JAR files as part of your web application. Like the Flex SDK, BlazeDS is an open-source project. More information is available at http://opensource.adobe.com.
In this document, we focus on the Remoting service. The Remoting Service provides a tight and natural integration with Spring. There is no need to transform data, or to expose services in a certain way: the Flex application can directly access the beans registered in the Spring IoC container.
So, if Flex clients can remotely access Java objects, and if Spring beans are Java objects, aren't we all set and ready to start accessing Spring beans from Flex clients? Almost… There is one simple element to configure.
The whole idea behind Spring IoC is to let the container instantiate components (and inject their dependencies). By default, however, components accessed remotely by a Flex client are instantiated by BlazeDS on the server. The key to the Flex/Spring integration, therefore, is to configure BlazeDS to let the Spring container take care of instantiating Spring beans. BlazeDS supports the concept of a factory to enable this type of custom component instantiation. The role of a factory is simply to provide ready-to-use instances of components to BlazeDS (instead of letting BlazeDS instantiate these components).
The supporting files available with this article include a factory class (SpringFactory) that provides BlazeDS with fully initialized (dependency-injected) instances of Spring beans. Note: The SpringFactory was developed by Jeff Vroom (Flex Data Services architect) and is also available on Adobe Exchange.
The remainder of this article describes how to configure your web application to use BlazeDS and Spring, how to configure the Spring Factory, and how to put the pieces together and start invoking Spring beans from Flex applications.
Configuring your web application is simple and merely requires installing and registering the necessary components.
The BlazeDS turnkey server is a ready-to-use version of Apache Tomcat in which the Blaze data services have already been deployed along with sample applications. The goal of the turnkey server is to give developers an easy way to run samples and tutorials out of the box.
As an alternative to using the turnkey server, you could use one of the following options:
The instructions in this document assume that you use the BlazeDS turnkey server. If you are using one of the alternative options, you will have to adjust the instructions accordingly.
You need the Flex compiler to compile the client-side (Flex-side) of the sample applications discussed in this document. The Flex compiler is part of the Flex SDK. As a convenience, the Flex SDK is available as part of the BlazeDS installation in blazeds/resources/flex_sdk/flex_sdk_3.zip.
You can skip this step if Flex Builder 3 is installed on your system.
Unzip /blazeds/resources/flex_sdk/flex_sdk_3.zip in /flex_sdk_3.
<context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener </listener-class> </listener>
Flex-spring.zip includes the Spring factory as well as the supporting files for the examples below.
<factories> <factory id="spring" class="flex.samples.factories.SpringFactory"/> </factories>
This first application is intentionally simplistic to provide an uncluttered example of wiring Spring beans together and invoking them from a Flex application.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean id="rateFinderBean" class="flex.samples.spring.mortgage.SimpleRateFinder"/> <bean id="mortgageBean" class="flex.samples.spring.mortgage.Mortgage"> <property name="rateFinder" ref="rateFinderBean"/> </bean> </beans>
Notice that in the mortgageBean definition, we tell the container how to inject the rateFinder dependency: the rateFinder property is mapped to rateFinderBean, which defines an instance of the SimpleRateFinder class.
<destination id="mortgageService"> <properties> <factory>spring</factory> <source>mortgageBean</source> </properties> </destination>
Notice that we use the Spring factory defined above (see "Register the Spring Factory"), and we provide the name of the Spring bean as defined in applicationContext.xml as the source.
The Flex SDK includes ANT tasks that make it easy to compile Flex applications and create HTML pages to host them as part of a build process. The support files include build scripts to compile and deploy each sample application.
The build process deploys the client side of the application (the compiled flex application) in /blazeds/tomcat/webapps/blazeds/mortgage and the server side (the compiled Java classes) in /blazeds/tomcat/webapps/blazeds/WEB-INF/classes/flex/samples/spring/mortgage.
This second example is more sophisticated and includes database connectivity. To keep the application simple and avoid dependencies on other products or frameworks, the Spring JDBC abstraction framework is used to access the database. You could use the Spring support for ORM data access (using Hibernate, JDO, Oracle TopLink, iBATIS, or JPA) as an alternative: the specific Spring data access strategy you choose has no impact on the Flex/Spring integration. This sample application has two modules: a database maintenance module (storeadmin) and a customer-facing product catalog with filtering capabilities (store).
Open store.mxml located in /flex-spring/samples/store/flex in a code editor to familiarize yourself with the store application. Notice the RemoteObject declaration pointing to the "productService" destination. "productService" is mapped to a Spring bean in Step 3 below. When the application starts, it invokes the findAll() method on the remote bean to retrieve the list of products (see the createComplete event on the Application tag).
Open storeadmin.mxml and ProductForm.mxml located in /flex-spring/samples/store/flex in a code editor to familiarize yourself with the storeadmin application. Notice that the storeadmin application uses the same remote Spring bean (productService) as the store application to retrieve the list of products using the findAll() method, and update changes using the updateProduct() method.
Open ProductDAO.java, SimpleProductDAO.java and Product.java located in /flex-spring/samples/store/java in a code editor. Notice that SimpleProductDAO extends org.springframework.jdbc.core.support.JdbcDaoSupport. JdbcDaoSupport has a dependency to a javax.sql.DataSource object (javax.sql.DataSource is an interface).
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="org.hsqldb.jdbcDriver"/> <property name="url" value=" jdbc:hsqldb:hsql://localhost:9002/flexdemodb"/> <property name="username" value="sa"/> <property name="password" value=""/> </bean> <bean id="productDAOBean" class="flex.samples.spring.store.SimpleProductDAO"> <property name="dataSource" ref="dataSource"/> </bean>
<destination id="productService"> <properties> <factory>spring</factory> <source>productDAOBean</source> </properties> </destination>
The build process deploys the client-side of the store and storeadmin applications in /blazeds/tomcat/webapps/blazeds/store and /blazeds/tomcat/webapps/blazeds/storeadmin respectively, and the server-side (the compiled Java classes) in /blazeds/tomcat/webapps/blazeds/WEB-INF/classes/flex/samples/spring/store.