Neil has posted 2 posts at DZone. View Full User Profile

Making Distinctions Between Different Kinds of JSF Managed-Beans

04.24.2009
| 40809 views |
  • submit to reddit
JSF has a simple Inversion-of-Control (IoC) container called the JSF Managed Bean Facility (MBF). Although it has a verbose XML syntax, and is not as robust as the Spring BeanFactory, PicoContainer, or the JBoss Microcontainer, the MBF does have the basics of an IoC container, and offers features like dependency injection.

When a POJO is managed by the JSF MBF, it is typically referred to as a managed-bean. But if you're going to create a maintainable JSF webapp/portlet, it is necessary to distinguish between different kinds of managed-beans. This practice will also preserve the clean separation of concerns that JSF provides by implementing the Model-View-Controller (MVC) design pattern:

 

Managed-Bean Type Nickname Typical Scope
Model Managed-Bean model-bean session

Description: This type of managed-bean participates in the "Model" concern of the MVC design pattern. When you see the word "model" -- think DATA. A JSF model-bean should be a POJO that follows the JavaBean design pattern with getters/setters encapsulating properties. The most common use case for a model bean is to be a database entity, or to simply represent a set of rows from the result set of a database query.

Backing Managed-Bean backing-bean request

Description: This type of managed-bean participates in the "View" concern of the MVC design pattern. The purpose of a backing-bean is to support UI logic, and has a 1::1 relationship with a JSF view, or a JSF form in a Facelet composition. Although it typically has JavaBean-style properties with associated getters/setters, these are properties of the View -- not of the underlying application data model. JSF backing-beans may also have JSF actionListener and valueChangeListener methods.

Controller Managed-Bean controller-bean request

Description: This type of managed-bean participates in the "Controller" concern of the MVC design pattern. The purpose of a controller bean is to execute some kind of business logic and return a navigation outcome to the JSF navigation-handler. JSF controller-beans typically have JSF action methods (and not actionListener methods).

Support Managed-Bean support-bean session / application

Description: This type of bean "supports" one or more views in the "View" concern of the MVC design pattern. The typical use case is supplying an ArrayList<SelectItem> to JSF h:selectOneMenu drop-down lists that appear in more than one JSF view. If the data in the dropdown lists is particular to the user, then the bean would be kept in session scope. However, if the data applies to all users (such as a dropdown lists of provinces), then the bean would be kept in application scope, so that it can be cached for all users.

Utility Managed-Bean utility-bean application

Description: This type of bean provides some type of "utility" function to one or more JSF views. A good example of this might be a FileUpload bean that can be reused in multiple web applications.

 

Now... One of the main benefits in making fine distinctions like this is loose coupling. What's that you ask? Well let's first take a look at an example of tight coupling, where MVC concerns can be smashed/confused into a single managed-bean:

 

public class ModelAndBackingAndControllerBean {

private String fullName; // model-bean property
private boolean privacyRendered; // backing-bean property

// model-bean getter
public String getFullName() {
return fullName;
}

// model-bean setter
public void setFullName(String fullName) {
this.fullName = fullName;
}

// backing-bean getter
public boolean isPrivacyRendered() {
return privacyRendered;
}

// backing-bean setter
public void setPrivacyRendered(boolean privacyRendered) {
this.privacyRendered = privacyRendered;
}

// backing-bean actionListener for UI support logic
public void togglePrivacySection(ActionEvent actionEvent) {
privacyRendered = !privacyRendered;
}

// controller-bean business logic
public String submit() {
System.out.println("fullName=" + fullName);
return "success";
}
}

The problem here is that the bean would have to be kept in session scope because of the model-bean property. Additionally, what if we wanted to do some unit testing with mock model data? Can't do it. So in order to fix these problems, and to promote loose coupling, we would have three separate Java classes:

public class ModelBean {

private String fullName;

public void setFullName(String fullName) {
this.fullName = fullName;
}

public String getFullName() {
return fullName;
}
}

public class BackingBean {

private boolean privacyRendered;

public void setPrivacyRendered(boolean privacyRendered) {
this.privacyRendered = privacyRendered;
}

public boolean isPrivacyRendered() {
return privacyRendered;
}

public void togglePrivacySection(ActionEvent actionEvent) {
privacyRendered = !privacyRendered;
}

}

public class ControllerBean {

private ModelBean modelBean;

public ModelBean getModelBean() {
return modelBean;
}

public void setModelBean(ModelBean modelBean) {
// Dependency injected from the JSF managed-bean facility
this.modelBean = modelBean;
}

public String submit() {
System.out.println("fullName=" + getModelBean().getFullName());
return "success";
}

}

 

Now that the beans are found in different classes, they can all be kept in their appropriate scopes. The model-bean can be kept in session scope, and the backing-bean and controller-bean can be kept in request scope, thus saving memory resources on the server.

Finally, we can use the dependency injection features of the JSF MBF in order to inject the model-bean into the controller-bean. This can be seen in the following WEB-INF/faces-config.xml example, where the #{modelBean} Expression Language (EL) binding is used:

<?xml version="1.0" encoding="UTF-8"?>
<faces-config xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd"
version="1.2">
<managed-bean>
<managed-bean-name>modelBean</managed-bean-name>
<managed-bean-class>myproject.ModelBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>backingBean</managed-bean-name>
<managed-bean-class>myproject.BackingBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>controllerBean</managed-bean-name>
<managed-bean-class>myproject.ControllerBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>modelBean</property-name>
<value>#{modelBean}</value>
</managed-property>
</managed-bean>
</faces-config>

 

From http://blog.icefaces.org/

Published at DZone with permission of its author, Neil Griffin.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Cloves Almeida replied on Fri, 2009/04/24 - 12:00pm

Or...

you  could go with Seam and release yourself from the JSF pain while still getting the benefits.

Pure JSF is component based UI development done wrong. Facelets+Seam+Annotations corrects it.

Otengi Miloskov replied on Sat, 2009/04/25 - 6:23pm

Yeah go with Seam and Facelets or Seam and Wicket. JSF is so broken. and plain ugly.

Serre replied on Sun, 2009/04/26 - 11:40pm

Hi,

Excellent article,

JSF is not broken and ugly if it is used in the right way.

Thanks

Casper Bang replied on Tue, 2009/04/28 - 2:42am

I think the only people liking JSF, are those who haven't tried true component oriented approaches like Wicket or GWT (each with their own approach to the transparent encapsulation og state). In JSF, the whole dilemma of session vs. request scoping of beans is enough to fragment a development department and confuse people. Also not sure what problem it solves to stuff absolutely everything into POST's, saying bye bye to adressability and transparency. Perhaps JSF is not broken, but it is just not particulary elegant nor easy to get things done.

Fadzlan Bin Yahya replied on Fri, 2009/05/01 - 7:04am

Seriously, use Seam.

 Then you dont have to akwardly manage your beans using only Session and Request. Code are much cleaner with better separation. Plus, you have whole slew of infrastructure given.

 And if you can understand JSF, seam would be really easy for you.

Coralie BONNEAU replied on Sat, 2009/05/16 - 2:55am

Do you have any working example ? (war, svn ...) I understand the theory but an example is welcome ! Thanks in advance, coralie.

Geovani Eidt replied on Tue, 2009/05/19 - 8:42am

I would like to have an example too! thanks!

Ed Burns replied on Wed, 2009/08/26 - 12:17pm

Very good article, Neil. Your article brings up an important point regarding framework design. One of the design decisions one makes in building a framework is "how prescriptive should the framework be for its users?" In other words, yes, people need hand holding but no, it shouldn't be the core runtime framework that does this hand holding.

With JSF, we really didn't want to be prescriptive in how people allocated concerns regarding their model tier. Because we decided to be open rather then closed in this way, articles such as yours are necessary to give novice developers a better understanding.

Ed Burns JSF Co spec lead.

P.S. Neil and I are collaborating on the second edition of my JSF Book. Get it on amazon at http://bit.ly/5qrXJ.

Saloucious Crumb replied on Tue, 2009/09/01 - 11:22am

yeah very nice article,

but what are you going to do when in your submit method, you have something like :

this.modelBean = myservice.findSomething(id);

 You could no longer decouple controller from model ....

 

Bob Rukket replied on Wed, 2009/09/16 - 3:03pm

Brilliant article for me! I am rather new to the JSF technology and always wondered, how to make the "gui near" application design. After reading this I was able to design what I wanted and it works fine. I must have a look Wicket (can I use this for portlet development?), but - in my opinion - JSF is a clear progress in Java based Web-Development. But it would be great, if the tool / IDE support for JSF implementations would be better.

Benoit Guerout replied on Thu, 2010/03/25 - 12:08pm

ModelAndBackingAndControllerBean looks like a Presentation Model...

Sakari Isoniemi replied on Fri, 2010/03/05 - 1:19am

Are the above comments about JSF still correct so that Wicket, Seam etc. frames are better UI component frames than latest JSF ( JSF 2.0 ) ? I don't quite understand how for, ex Seam managed components are better alternative than JSF managed beans ?

Veeramani Kalya... replied on Thu, 2011/02/17 - 1:29am

Good article Neil

But when you keep the model bean in session don't the performance issue will come as any app server memory will buldge out soon.

 Regards

Veera

Paul Meshkovsky replied on Wed, 2012/08/15 - 1:12pm

Great Atricle! This served as inspiration for one of our projects in order wich Desing Pattern to Apply when working with JSF.

I do have a comment to make.  The Backing Bean to support view logic does not exist in MVC desing pattern rather it exists in MVP desing pattern.

Therefore  the Controller Bean should be combined  with Backing Bean and there you have a Presenter wich provides outcomes that are handled by JSF Controller part of MVP

 The Model ManagedBean can actually be considered Presentation Model that in enterpris wold can Wrap Domain Objects in order to corretly display, edit Domain Objects.

 

 

 

 

 

 

 

 

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.