An inline flow has the exact same behavior as a subflow; they are both flows, but inline
flows exist entirely within the containing flow definition and are local to that definition. The
general strategy for extracting an inline flow is as follows:
1.Move the flow fragment into an <inline-flow>element within the parent flow.
2.If the fragment was previously a top-level flow, remove the flow from the flowRegistry.
Applying step 1 to /WEB-INF/flows/purchase-flow.xmlmakes the shipping flow an inline
flow, as shown in Listing 12-10. Notice how the parent subflow state doesn’t change. There is
no difference between calling either a top-level flow or an inline flow as a subflow. An inline
flow by definition must simply be declared (and fully contained) within the calling flow.
■Tip Subflows are retrieved via the flowRegistrymechanism, while inline flows are declared within the
same flow.
Listing 12-10./WEB-INF/flows/purchase-flow.xmlwith the Shipping Flow As an Inline Flow
<flow start-state="enterPurchaseInformation">
<view-state id="enterPurchaseInformation" view="purchaseForm">
<entry-actions>
<action bean="formAction" method="setupForm"/>
</entry-actions>
<transition on="submit" to="enterShippingInformation">
<action bean="formAction" method="bindAndValidate"/>
</transition>
<transition on="cancel" to="cancel"/>
</view-state>
<subflow-state id="enterShippingInformation" flow="shipping-flow">
<attribute-mapper>
<input-mapping name="purchase.requiresShipping"➥
as="requiresShipping"/>
<output-mapping name="shipping" as="purchase.shipping"/>
</attribute-mapper>
<transition on="finish" to="placeOrder"/>
</subflow-state>
<action-state id="placeOrder">
<action bean="orderClerk" method="placeOrder(${ flowScope.purchase})"/>
<transition on="success" to="showCostConfirmation"/>
</action-state>
<end-state id="showCostConfirmation" view="costConfirmation"/>
<end-state id="cancel" view="home"/>
<import resource="purchase-flow-context.xml"/>
344 CHAPTER 12 ■ADVANCED SPRING WEB FLOW