|
Ioc
PurposeThis purpose of the rocket.Beans module is to bring many of the features made popular and available to regular java via Spring to GWT authored client applications. This wiki does not attempt to discuss or educate on why or how Spring and dependency injection or ioc works but rather how to use whats been built in rockets implementation. Getting startedImporting the rocket.Beans moduleAdd the following import statement to your own applications module. <module> ... <inherits name="rocket.beans.Beans" /> Whats supportedWhilst most of the basic Spring DI features are available not all of them currently are. Some reasons for this include the limitations of how GWT java works. Bean scopes
Lifecycle control
Special interfaces
Factory BeansFactoryBeans within a rocket bean factory perform the same role of being responsible for the construction of a bean on request by the parent bean factory. Because class objects are not available within the GWT environment an annotation is used to tell notify the bean factory generator what type of bean is being produced.
InterceptorsAll the method advices and interceptors available in spring are available with some minor differences.
PropertiesJust about all the property types supported by spring are supported in rocket.
Extras
Authoring a bean factory xml fileThe xml file format contains many similarities with a typical Spring file. beanThe bean tag includes a number of attributes that help define a single bean.
The example below creates a prototype bean (the example skips setting any properties). <bean id="magic" class="example.client.Magic" scope="prototype" factory="create" initMethod="init" /> constructorIntroducing the constructor tag within a bean allows the bean to be created using a constructor with one or more parameter values. Naturally the values (child value tags) must be compatible with any public constructor belonging to the bean class. More about value tags further down. properties / propertyThe properties tag is a container for one or more individual properties to be set upon a bean. Each property requires a property name and value. Properties are not limited to just The example below shows how to set a property called name with a String value of "rocket". The xml below assumes the bean class has a setter for this property etc. <bean ... > <properties> <property name="name"> <value>rocket</value> nullThis value may be used to set null values upon a property or constructor argument. valueThis tag may be used to set a primitive or String value upon a property or constructor argument. Primitive values are any of the following:
<bean ... > <properties> <property name="name"> <value>true</value> </property> imagesThe image tag may be used to set an image property. Behind the scenes an ImageFactory is generated which means that for supported browsers data urls will be used. The example below sets an image property belonging to a bean. Take note that IE clients will download the image from a server whilst users of other browsers will source the image from a data url. <bean ... > <properties> <property name="someImage"> <image file="/image.jpg" location="local"/> </property> bean-referenceThis tag allows a bean property to set with another bean reference. The example below assumes a property called "anotherBean" has a setter that is compatible with the type of "theOtherBean". If any of these arent true the generator complains. <bean ... > <properties> <property name="anotherBean"> <bean-reference reference-id="theOtherBean" </property> nested beanIt is also possible to define a nested bean as a property of another bean. The example below embeds the definition of theOtherBean rather than using the bean-reference of the example above. <bean ... > <properties> <property name="anotherBean"> <bean <!-- rather than bean-reference theOtherBean simply includes its bean definition here --> </property> list, set, mapThe list, set, map tags may be used to set a list, set or map property belonging to a bean. Any valid value tag (null,value,bean,bean-reference) may be an element or value of these collection types. The example below populates each of the three collection types using the three tags. <bean ... > <properties> <property name="listProperty"> <list> <value>this list element is a String</value> </list> </property> <property name="setProperty"> <set> <value>this set element is a String</value> </set> </property> <property name="mapProperty"> <map> <map-entry key="the map key"> <value>this map value is a String</value> </map> </map> </property> rpcThe rpc tag may be used to create a bean that is actually of the following rpc types.
The tag needs three attributes to define the properties of the rpc bean.
adviceAny bean may have one or more advices. Unfortunately advices allocations to beans is static and can only be via a definition(s) appearing in the xml file and cannot be done at runtime. aliasThe alias tag may be used to introduce an alias for a bean. References to the bean may be to any of its alias or the bean's id itself. Using is equivalent in terms of the end result, ie using the alias or bean results in the same bean being delivered by the BeanFactory. includeThis may be used to include another bean factory xml file. All bean definitions for the main file and included files are available in the resulting BeanFactory.
The example below adds the definitions present in the MoreBeans.xml file to the current xml file. <include file="/example/client/MoreBeans.xml" placeholderThe placeholder tag loads a property file containing key/value pairs. Any placeholders found in an element or attribute in the parent xml file are substituted by values from the placeholder. <include file="<ithe name of the properties file shown below>">
<bean id="bean"
class="${beanClassName}
...The contents of the properties file beanClassName=example.client.Bean The end result is the bean called "bean" will be of type "example.client.Bean". Working with the BeanFactoryBecause Gwt does not support runtime reflection, a GWT generator has been written which transforms a BeanFactory.xml into a class that implements the 'rocket.beans.client.BeanFactory' interface. All beans defined in the xml file may be retrieved using the getBean(String) method passing the name of the bean. If the bean doesnt exist or cannot be created an exception is thrown. As noted above each xml file has an accompanying sub interface of BeanFactory. Deferred binding is used to retrieve the class that is the BeanFactory. The example below retrieves a BeanFactory generated from the xml file found in /examples/client/BeanFactory.xml. The second line of code, then retrieves a bean called "someBean", with all dependencies and other dependency injection features satisfied. The third line makes a request to the factory to question whether or not the bean is a singleton return true because it is. // realize bean factory from xml file. this is done at compile time. rocket.beans.client.BeanFactory myBeanFactory = (rocket.beans.client.BeanFactory) GWT.create( examples.client.BeanFactory.class ); // fetch a bean called foo example.client.Bean foo = (example.client.Bean) myBeanFactory.getBean( "someBean" ); // is foo a singleton ? it should be... System.out.println( myBeanFactory.isSingleton( "someBean" )); More examplesThe beans module was developed using Test Driven Development (TDD) approach and thus contains many unit tests. Practically each and every feature that is supported includes an accompanying test which also includes an xml file that illustrates how its done in xml. The factory beans, and interceptors are tested using simple unit tests. The actual generator which does the magic of transforming the xml file into a BeanFactory has its own GWT Test The table below lists some examples.
The BeansGwtTestCase includes many tests each with accompanying xml file that illustrates the feature being tested. Each test includes a sub package of the almost the same name with all related files. | ||||||||||||||||||||