Making Distinctions Between Different Kinds of Jsf Managed-Beans

Making Distinctions Between Different Kinds of JSF Managed-Beans

This is a very subjective question. I personally disagree that article and find that it's giving really bad advice to starters.


Model Managed-Bean: 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.

I would absolutely not make or call it a managed bean. Just make it a property of a @ManagedBean. For example a DTO or JPA @Entity.


Backing Managed-Bean: 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.

This way you keep duplicating and mapping the properties of the entity in the managed bean. This makes no sense to me. As said, just make the entity a property of the managed bean and let the input fields refer it directly like #{authenticator.user.name} instead of #{authenticator.username}.


Controller Managed-Bean: 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).

This describes the @RequestScoped/@ViewScoped @ManagedBean class pretty much. Whether event listener methods are allowed or not depends on whether they are specific to the view which is tied to the bean and/or are for their job dependent on the bean's state. If they are, then they belongs in the bean. If not, then they should be a standalone implementation of any FacesListener interface, but definitely not a managed bean.


Support Managed-Bean: 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 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.

Fine. For application wide data like dropdown lists just use an @ApplicationScoped bean and for session wide data like logged-in user and its preferences just use a @SessionScoped one.


Utility Managed-Bean: 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.

This makes not really sense to me. Backing beans are usually tied to single views. This sounds too much like an ActionListener implementation which is to be used by <f:actionListener> in command components to your choice. Definitely not a managed bean.

For kickoff examples of the right approach, see also:

  • Hello World example in Our JSF wiki page
  • "Bookstore CRUD" example in this answer
  • "Master-detail" example in this answer
  • JSF Service Layer
  • Communication in JSF 2

Making Distinctions Between Different Kinds of JSF Managed-Beans

This is a very subjective question. I personally disagree that article and find that it's giving really bad advice to starters.


Model Managed-Bean: 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.

I would absolutely not make or call it a managed bean. Just make it a property of a @ManagedBean. For example a DTO or JPA @Entity.


Backing Managed-Bean: 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.

This way you keep duplicating and mapping the properties of the entity in the managed bean. This makes no sense to me. As said, just make the entity a property of the managed bean and let the input fields refer it directly like #{authenticator.user.name} instead of #{authenticator.username}.


Controller Managed-Bean: 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).

This describes the @RequestScoped/@ViewScoped @ManagedBean class pretty much. Whether event listener methods are allowed or not depends on whether they are specific to the view which is tied to the bean and/or are for their job dependent on the bean's state. If they are, then they belongs in the bean. If not, then they should be a standalone implementation of any FacesListener interface, but definitely not a managed bean.


Support Managed-Bean: 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 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.

Fine. For application wide data like dropdown lists just use an @ApplicationScoped bean and for session wide data like logged-in user and its preferences just use a @SessionScoped one.


Utility Managed-Bean: 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.

This makes not really sense to me. Backing beans are usually tied to single views. This sounds too much like an ActionListener implementation which is to be used by <f:actionListener> in command components to your choice. Definitely not a managed bean.

For kickoff examples of the right approach, see also:

  • Hello World example in Our JSF wiki page
  • "Bookstore CRUD" example in this answer
  • "Master-detail" example in this answer
  • JSF Service Layer
  • Communication in JSF 2

Difference between managed bean and backing bean

Changing my initial answer - there is no meaningful difference between the two. The tutorial says that backing beans are later declared as managed beans. So, to summarize:

  • a backing bean is the class out of context
  • a managed bean is the backing bean whenever it is declared to be used with the JSF managed bean facility.

I've never actually used the term "backing bean", because I found no use to it. So you might be better off using only "managed bean". Note that in JSF 2.0 (and in CDI) you have @ManagedBean- so your bean is a managed bean.

BalusC suggested that "backing bean" is the definition, and "managed bean" is the instance. While this might have been the original idea of JSF creators, I don't think it is worth supporting it. CDI and spring for example don't have different term for "bean definition" and "bean instance".

The JSF 2.0 specification mentions the term "backing bean" only a few times, with no definition whatsoever. In addition to that it mentions "backing bean class", which might mean that "backing bean" != "backing bean class", which brings further confusion.

So to conclude - for me both are interchangeable, and I'd stick to only using "managed bean"

How to add multiple instances of JSF 2 managed beans to Java Collection?

Make Bean2 a managed property of Bean1 so that you have access to its beanList property.

@ManagedBean
public class Bean1 {
private String foo;
private String bar;

@ManagedProperty("#{bean2}")
private Bean2 bean2;

public void submit() {
bean2.getBeanList().add(this);
// ...
}

// ...
}

(please note that this way just the reference is stored, not a clone of the Bean1's state or something!)

Needless to say that this is a design smell. There are likely better ways to achieve the concrete functional requirement which you've had in mind while asking the question but didn't tell anything about. In the future try to ask how to solve the functional requirement instead of how to achieve a solution (which may not be the right solution after all).

Whats the correct way to create multiple instances of managed beans in JSF 2.0

You can't. It technically also doesn't make much sense. You're probably looking for a solution in the wrong direction for the particular functional requirement.

Your best bet is to have a parent bean and have those "multiple beans" as children.

@ManagedBean
@RequestScoped
public class Parent {
private Child child1;
private Child child2;
// ...
}

so that you can access it by #{parent.child1} and #{parent.child2}. You can of course also use a List<Child> property or even Map<String, Child> instead to be more flexible.

With the faces-config.xml it's however possible to define multiple bean classes with a different name. Still then, I don't see how that's useful.

How to declare many JSF managed beans at once

Just make the User a property of UserService. That's also more conform JSF's MVC ideology. The UserService is the controller and the User is the model.

Thus so,

@ManagedBean
@ViewScoped
public class UserService {

private User user;

// ... (don't forget to prepare user in (post)constructor if "new" user)
}

with

<h:inputText value="#{userService.user.name}" />
<h:inputText value="#{userService.user.password}" />


Related Topics



Leave a reply



Submit