ADF Task Flow: Managed bean scopes for page fragments

Introduction

When we work with ADF Task Flows and need to implement some flow specific business logic or store some information connected with the flow, we usually use pageFlowScope managed beans. And when we need to service view activities of the flow (pages or page fragments) we use shorter scopes for such managed beans. The common practice is to use requestScope, backingBeanScope and viewScope scopes for pages/fragments backing beans. In this post I’m going to play with these three options and discover the differences in the behavior of fragment based Task Flow.

Let’s say I have some simple task flow template task-flow-template.xml:

   
    <managed-bean id="__5">
      <managed-bean-name id="__3">viewBean</managed-bean-name>
      <managed-bean-class id="__2">com.cs.blog.ViewBean</managed-bean-class>
      <managed-bean-scope id="__4">request</managed-bean-scope>
    </managed-bean>
    <managed-bean id="__15">
      <managed-bean-name id="__13">flowBean</managed-bean-name>
      <managed-bean-class id="__12">com.cs.blog.FlowBean</managed-bean-class>
      <managed-bean-scope id="__14">pageFlow</managed-bean-scope>
    </managed-bean>

    <view id="MainView">
      <page>/MainView.jsff</page>
    </view>
    

It has one view activity MainView and two backing beans. The flowBean has pageFlow scope and is responsible to store flow information. The viewBean has request scope (we will play with that) and it services the ManView view activity.

The flowBean has the following method returning the tittle of the task flow:

    public String getFlowTitle() {
        return null;
     }   

The viewBean has some string field testString to store input value:

    protected String testString;
    
    public void setTestString(String testString) {
        this.testString = testString;
    }

    public String getTestString() {
        return testString;
    }

The MainView shows the task flow’s title and has an inputText for the testString. It looks like this:

We also have two task flows built on the task-flow-template – first-flow-definition and second-flow-definition. They have overridden managed beans.

For the first-flow-definition:

    <managed-bean id="__5">
      <managed-bean-name id="__3">viewBean</managed-bean-name>
      <managed-bean-class id="__21">com.cs.blog.FirstViewBean</managed-bean-class>
      <managed-bean-scope id="__4">request</managed-bean-scope>
    </managed-bean>    
    
    <managed-bean id="__15">
      <managed-bean-name id="__13">flowBean</managed-bean-name>
      <managed-bean-class id="__12">com.cs.blog.FirstFlowBean</managed-bean-class>
      <managed-bean-scope id="__14">pageFlow</managed-bean-scope>
    </managed-bean>
 
public class FirstFlowBean extends FlowBean {
    public FirstFlowBean() {
        super();
    }
    
    public String getFlowTitle() {
        return "FirstFlow";
     }   
   
}
public class FirstViewBean extends ViewBean {
    public FirstViewBean() {
        super();
        
    }
    
    @PostConstruct
    public void init() {
        testString = "FirstFlow";  
    }
}

So the title and default value for testString is “FirstFlow”.

For the second-flow-definition:

    <managed-bean id="__5">
      <managed-bean-name id="__3">viewBean</managed-bean-name>
      <managed-bean-class id="__21">com.cs.blog.SecondViewBean</managed-bean-class>
      <managed-bean-scope id="__4">request</managed-bean-scope>
    </managed-bean>    
    
    <managed-bean id="__15">
      <managed-bean-name id="__13">flowBean</managed-bean-name>
      <managed-bean-class id="__12">com.cs.blog.SecondFlowBean</managed-bean-class>
      <managed-bean-scope id="__14">pageFlow</managed-bean-scope>
    </managed-bean>
public class SecondFlowBean extends FlowBean {
    public SecondfFowBean() {
        super();
    }
    
    public String getFlowTitle() {
        return "SecondFlow";
     }   
    
}
public class SecondViewBean extends ViewBean {
    public SecondViewBean() {
        super();
       
    }
   
    @PostConstruct
    public void init() {
        testString = "SecondFlow"; 
    }
   
}

So the title and default value for testString is “SecondFlow”.

Ok. It’s time to experiment. Let’s put on our page two regions with first-flow-definition and second-flow-definition task flows:

              
<af:region value="#{bindings.firstflowdefinition1.regionModel}" id="r1"/>
<af:separator id="s1"/>           
<af:region value="#{bindings.secondflowdefinition1.regionModel}" id="r2" />

requestScope

Leaving the scope for the viewBean as requestScope we will get the following result:

In the SecondFlow we see the testString from the FirstViewBean instance. We can have only one instance of the requestScope bean per request. The viewBean was created for the FirstFlow task flow and the same instance was used again for the SecondFlow.

backingBeanScope
 

Somebody could recommend to use backingBeanScope for the viewBean instead of requestScope. The backingBeanScope is commonly used to manage regions and declarative components. It has the same length of life as the requestScope but for different instances of regions/declarative components you will have separate instances of backingBean scoped managed beans. In our case we have two different regions, so let’s try:

And, Yes, the backingBeanScope has fixed the problem. We have two instances of the viewBean – for the regions r1 and r2.

But let’s make the first-flow-definition task flow a bit more complicated:

Now we can call child task flow (of the same definition) from the MainView. And let’s repeat the experiment. On the initial rendering:

 

So far, so good. Let’s input something in the input text of the FirstFlow and press “call child task flow”:

Oooops! We have only one instance of the viewBean for the region r1 during the request. So, value “FirstFlow111111″ entered in the parent task flow was rendered again in the child task flow.

viewScope
 
And now let’s change the viewBean’s scope to the viewScope and have the same experiment. On the initial rendering:

 

Ok. Inputting the same garbage in the inputText:

And pressing the “call child task flow”:

And everything is ok. We have not only separate viewScope beans instances for different viewport IDs (for different regions and task flow instances), but additionally the controller is resetting the viewScope during the navigation process. But the cheese is not free. You have to pay by memory. If requestScope or backingBeanScope live not longer than the request, viewScope lives in memory until the viewport ID is changed. Perhaps in my further posts I will show how to manage the issue with the backingBeanScope.
So, when you choose the appropriate scope for your fragment managed beans, consider how the task flow is going to be used. Probably, in order to get really high reusable task flow, using the viewScope is the best approach for fragment beans.

That’s it!

Reference: Managed bean scopes for page fragments in ADF Task Flow from our JCG partner Eugene Fedorenko at the ADF Practice blog.

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

JPA Mini Book

Learn how to leverage the power of JPA in order to create robust and flexible Java applications. With this Mini Book, you will get introduced to JPA and smoothly transition to more advanced concepts.

JVM Troubleshooting Guide

The Java virtual machine is really the foundation of any Java EE platform. Learn how to master it with this advanced guide!

Given email address is already subscribed, thank you!
Oops. Something went wrong. Please try again later.
Please provide a valid email address.
Thank you, your sign-up request was successful! Please check your e-mail inbox.
Please complete the CAPTCHA.
Please fill in the required fields.

Leave a Reply


seven + = 10



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close