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

Ste*_*han 7 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 ...
}
Run Code Online (Sandbox Code Playgroud)


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

为什么JSF不会被FooBean视为托管bean?

Ric*_*cia 9

亚历克斯试图做的一点就是你把类与实例混淆了.这是一个经典的(双关语)OOP错误.

@ManagedBean注释不适用于类本身.它适用于情况下这样的类的,定义为可管理的实例.

如果您的bean定义如下:

@ManagedBean
@SessionScoped
public class MyBean implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
}
Run Code Online (Sandbox Code Playgroud)

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

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

所以,假设你有另一个类:

Class MyOtherClass {
    private MyBean myBeanObject; // myBeanObject isn't managed. 
}
Run Code Online (Sandbox Code Playgroud)

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

但是,当您执行此操作时,事情会完全改变:

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

    public void setMyBeanObject(...) { ... }
    public MyBeanClass getMyBeanObject() { ... }
}
Run Code Online (Sandbox Code Playgroud)

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


Tha*_*ham 5

你需要BaseBean成为一个托管bean吗?既然你命名它BaseBean,我认为这个bean在你所有其他托管bean之间保持通用性.如果是这样,那么它不应该包含@ManagedBean注释.做这个

public abstract BaseBean{
    //...
}
Run Code Online (Sandbox Code Playgroud)

然后在你的托管bean里面

@ManagedBean
@RequestScoped
public class FooBean extends BaseBean{
    //...
}
Run Code Online (Sandbox Code Playgroud)

  • @Stephan:为什么要避免在所有托管bean上添加注释?我不知道你把你​​的`BaseBean`里面,但是从你的名字的方式,它都应该管理的bean之间设置共性的,所以你不应该注释它@ManagedBean,因为它是不是一个真正的控制器/网关你的'模特'.你的`BaseBean`是`SessionScoped`,所以从`BaseBean`继承的每个bean都是SessionScoped,无论你是否想要它.你不想在Session中保留太多东西.如果要创建具有RequestScoped并继承`BaseBean`的托管bean,该怎么办? (2认同)