POJO Actions
Chapter 11 defined the Actionas the central construct for executing your application code
from within a flow definition. It also stated that every actionbean had to implement the
org.springframework.webflow.Action interface. And this is true. Every Spring Web Flow
actionbean does need to implement the Actioninterface, but Spring Web Flow will do a
bit of magic for you so you aren’t forced into writing custom action glue code just to invoke
methods on your business services.
When you reference a bean that doesn’t implement the Actioninterface (a plain old Java
object (POJO), http://en.wikipedia.org/wiki/Plain_Old_Java_Object), Spring Web Flow
will create a new instance of org.springframework.webflow.action.LocalBeanInvokingAction
to automatically adapt a method on your class to the Actioninterface. The purpose of
LocalBeanInvokingActionis to be an adapter(http://en.wikipedia.org/wiki/Adapter_
pattern) between the Spring Web Flow Actioninterface and a method on your class. Let’s
look again at the XML fragment that declares the POJO bean that will be used as an action:
Listing 12-23.The placeOrder Action
<action-state id="placeOrder">
<action bean="orderClerk" method="placeOrder(${flowScope.purchase})"/>
<transition on="success" to="showCostConfirmation"/>
</action-state>
When Spring Web Flow encounters this fragment, it will construct an instance of
LocalBeanInvokingActionand pass it a reference to your bean (orderClerk), and the signature
of the method you want invoked (placeOrder(${flowScope.purchase}). When Spring Web
Flow executes the actionbean (by calling LocalBeanInvokingAction.doExecute()), the method
you specified will be invoked on the bean you provided.
■NoteSpring Web Flow delegates the actual execution of your method to an instance of org.spring
framework.binding.method.MethodInvoker,part of the Spring Framework method binding
infrastructure.
In the XML fragment Spring Web Flow was instructed to pass in the value of the expres-
sion ${flowScope.purchase}(i.e., the object stored under the name purchasein flow scope) to
the placeOrdermethod.
The result of MethodInvoker.invoke()is a java.lang.Object. If your method signature was
void, this will be null; if your method returned a primitive it will be automatically converted to
the java.lang.Objectequivalent (booleanto java.lang.Booleanand the like).
362 CHAPTER 12 ■ADVANCED SPRING WEB FLOW