我有一个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?
答案 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{
//...
}