【问题标题】:calling @PostConstruct on super bean AND extending bean在超级 bean 和扩展 bean 上调用 @PostConstruct
【发布时间】:2012-06-26 18:55:19
【问题描述】:

我有一个带有@PostConstruct 的BaseBean,以及一个扩展它的bean,我想在其上调用另一个@PostConstruct。我已经阅读了几个地方说它是可能的,但是,似乎首先调用了扩展类上的@postConstruct(如果完全调用了第二个)。然后我在“上下文”上得到一个 NPE,因为我假设超级 bean 的 PostConstruct 已经被调用。

这是可行的吗?如果是这样,我做错了什么?

基础 bean:

@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);
}

谢谢, 尤塔姆。

【问题讨论】:

  • @YotamSeon 我有一个非常相似的问题here。您是否认为接受的建议是您唯一可以解决的问题?

标签: jsf postconstruct


【解决方案1】:

在构建托管 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,只在{smartBoxSearchBean}中注入#{baseBean}

@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);
    }

}

【讨论】:

  • 感谢 BalusC 的超级快速回答。您的解决方案可以工作,除了一个问题 - 在 BaseBean 的 PostConstruct 中,我还初始化了扩展 bean 使用的其他成员...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-23
  • 2015-06-01
  • 1970-01-01
相关资源
最近更新 更多