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

3

7

If I want to create more than one instance of managed bean in JSF 2.0, under different names in the same scope, how should I proceed? Ideally, I want the equivilant to (for example):

@ManagedBeans({name="myManagedBean1",name="myManagedBean2"})
@RequestScoped
public class MyManagedBean {

}

Thanks ..

Mediant answered 14/9, 2010 at 14:53 Comment(1)
I think JSF 2.0 annotations should be as powerful as faces-config.xml already is in relation to bean creation. I have been using multiple beans of the same class in JSF 1.2 and it's a pity JSF2.0 doesn't overcome this feature with annotations.Coston
B
11

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.

Bouncer answered 14/9, 2010 at 15:22 Comment(4)
Thanks. The requirement stems from the managed beans in question being backing beans for custom components, which have some fields bound to UIComponents on the page. Thus (albiet on rare occasions), I need multiple instance of the same type of backing bean for several of the same components, in this case UI dialogs. I thought your solution might be the case, but then this leaves one unable to use lifecycle annotations such as @PostConstruct. Thanks!Mediant
You can create multiple instances of a ManagedBean (override ManagedBeanELResolver's getValue). They will be build using the same BeanBuilder and BeanManager, they just differ in their beanName. If it is necessary for your solution, I don't know. In some rare cases, I would say yes.Warden
@Manual: Surely it's possible. The main answer just applies to using JSF 2.0 annotations to achieve the goal, exactly as the OP asked. Note that the last paragraph of the answer states that it's possible to define multiple instances when using the old faces-config.xml way instead. For that you don't need to hack the JSF impl specific classes.Bouncer
A use case for me, is a common search criteria bean. This bean stores user search criteria. I like to retain the criteria to make it easier for the user when it comes back to the same web page. However, I might need the same search bean in different web pages. Hence I don't want search criteria to be altered for each page. Hence the same bean with a different name for me.Wong
P
3

In your case you should make use of the faces-config.xml. Implment your bean without the ManagedBean and RequestScope annotation. So your bean will not become a managed bean per default. You can than instance as much managedBeans as you need with different names, different scopes and at lease differnent properties. For example:

    <managed-bean>
    <managed-bean-name>MyManagedBean1</managed-bean-name>
    <managed-bean-class>org.MyManagedBean</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
    <managed-property>
        <property-name>value1</property-name>
        <property-class>int</property-class>
        <value>5</value>
    </managed-property>
    <managed-property>
        <property-name>value2</property-name>
        <property-class>int</property-class>
        <value>2</value>
    </managed-property>
</managed-bean>

<managed-bean>
    <managed-bean-name>MyManagedBean2</managed-bean-name>
    <managed-bean-class>org.MyManagedBean</managed-bean-class>
    <managed-bean-scope>view</managed-bean-scope>
    <managed-property>
        <property-name>value1</property-name>
        <property-class>int</property-class>
        <value>30</value>
    </managed-property>
    <managed-property>
        <property-name>value2</property-name>
        <property-class>java.lang.String</property-class>
        <value>project</value>
    </managed-property>
</managed-bean>

Don't think that descriptors are evil and annotations are the only way to implement your code.

Pompom answered 6/9, 2012 at 22:18 Comment(0)
T
3

One possibility is to make your class abstract and subclass it into as many named instances as you need, which you may leave empty. This will also help you separate future managed bean functionality which really only concerns one of the cases.

You will have to move the @ManagedBean (and scope) annotation to all the subclasses, regrettably, even though it is @Inherited. For the current version of Mojarra atleast, others I don't know.

Trier answered 14/12, 2012 at 13:40 Comment(1)
For my use case above, I decided to go with this approach since there are different init cases for each different web page such as. Thanks.Wong

© 2022 - 2024 — McMap. All rights reserved.