在super bean和扩展bean上调用@PostConstruct

时间:2012-06-26 18:55:20

标签: jsf postconstruct

我有一个带有@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。

1 个答案:

答案 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);
    }

}