JSF 2:是否可以继承@ManagedBean?

时间:2011-07-08 16:20:21

标签: java jsf inheritance

我有一个Bean,带有@ManagedBean注释,定义如下:


@ManagedBean
@SessionScoped
public class Bean implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

}

现在,我有另一个像这样定义的bean:


public class FooBean extends Bean {
    // properties, methods here ...
}


当我尝试在我的JSF页面中引用FooBean时,出现以下错误:
Target Unreachable, identifier 'fooBean' resolved to null

为什么JSF没有将FooBean视为托管bean?

2 个答案:

答案 0 :(得分:9)

Alex试图提出的一点是,你将类与实例混淆。这是一个经典的(双关语)OOP错误。

@ManagedBean批注对类本身不起作用。它适用于此类的实例,定义了托管的实例。

如果您的bean定义如下:

@ManagedBean
@SessionScoped
public class MyBean implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
}

然后它意味着您有一个会话范围的实例,名为myBean(或任何您想要命名的)。

因此,默认情况下不管理作为MyBean 的子类的所有类。此外,JSF如何识别您使用子类的位置?如果是这样,你给这些实例的名字是什么? (因为你必须给它们一些名字,否则,JSF将如何管理它们?)

所以,假设你有另一个班级:

Class MyOtherClass {
    private MyBean myBeanObject; // myBeanObject isn't managed. 
}

@PostConstruct和您使用的所有其他注释会发生什么?没有。如果您创建了MyBean的实例,则由您管理它,而不是JavaServerFaces。所以它不是一个托管bean,只是你使用的常见对象。

然而,当你这样做时,事情会完全改变:

@ManagedBean
@SessionScoped
Class MyOtherClassBean {
    @ManagedProperty("#{myBean}")
    private MyBean myBeanObject;

    public void setMyBeanObject(...) { ... }
    public MyBeanClass getMyBeanObject() { ... }
}

然后,托管的不是类,而是类的实例。拥有ManagedBean意味着您只有该bean的一个实例(每个范围,即)。

答案 1 :(得分:5)

你需要BaseBean成为托管bean吗?由于您将其命名为BaseBean,因此我假设此bean在所有其他托管bean之间保持通用性。如果是,那么它不应包含@ManagedBean注释。这样做

public abstract BaseBean{
    //...
}

然后在托管bean中

@ManagedBean
@RequestScoped
public class FooBean extends BaseBean{
    //...
}