我有一个带有@PostConstruct的BaseBean,以及一个扩展它的bean,我想调用另一个@PostConstruct。我已经阅读了几个可能的地方,但是,似乎首先调用扩展类的@postConstruct(如果第二个被调用的话)。然后我在“上下文”中得到一个NPE,因为我假设已经调用了超级bean的PostConstruct。
这可行吗?如果是这样,我做错了什么?
基础豆:
@ManagedBean
@RequestScoped
public class BaseBean {
@ManagedProperty(value = "#{contextBean}")
private ContextBean contextBean;
Context context;
@PostConstruct
public void setupContext() {
context = getContextBean().getContext();
}
扩展bean:
@ManagedBean
@RequestScoped
public class SmartBoxSearchBean extends BaseBean {
@PostConstruct
public void setUp() {
jsonHelper = context.get(SmartBoxJsonHelper.class);
}
谢谢, Yotam。
答案 0 :(得分:10)
构造托管bean时,根本不会调用支持bean的超类的@PostConstruct
。只有当一个超级类的完全独立的托管bean实例被构建时,才会调用它。在你的案例中使用EL中的#{baseBean}
。您实际上最终得到了两个完全独立的实例#{baseBean}
和#{smartBoxSearchBean}
,其中类'自己的@PostConstruct
方法在托管bean类本身上独立调用。
这种设计有些奇怪。支持bean的超类通常根本不用作托管bean。
我建议修改你的方法如下:
public abstract class BaseBean {
@ManagedProperty("#{contextBean}")
private ContextBean contextBean;
public Context getContext() {
return contextBean.getContext();
}
}
和
@ManagedBean
@RequestScoped
public class SmartBoxSearchBean extends BaseBean {
@PostConstruct
public void setUp() {
jsonHelper = getContext().get(SmartBoxJsonHelper.class);
}
}
或者也许是这样,如果您不需要ContextBean
用于其他目的
public abstract class BaseBean {
@ManagedProperty("#{contextBean.context}")
private Context context;
public Context getContext() {
return context;
}
}
注意@ManagedProperty
以这种方式在超类中声明时效果很好。
更新:根据功能要求,您还可以将bean分离,只需在#{baseBean}
中注入{smartBoxSearchBean}
。
@ManagedBean
@RequestScoped
public class BaseBean {
@ManagedProperty("#{contextBean}")
private ContextBean contextBean;
private Context context;
@PostConstruct
public void init() {
context = contextBean.getContext();
}
}
和
@ManagedBean
@RequestScoped
public class SmartBoxSearchBean {
@ManagedProperty("#{baseBean}")
private BaseBean baseBean;
@PostConstruct
public void setUp() {
jsonHelper = baseBean.getContext().get(SmartBoxJsonHelper.class);
}
}