在超级bean和扩展bean上调用@PostConstruct [英] calling @PostConstruct on super bean AND extending bean

查看:167
本文介绍了在超级bean和扩展bean上调用@PostConstruct的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a BaseBean with a @PostConstruct, and a bean extending it on which i would like to call another @PostConstruct. I have read several places where it said it was possible, however, it seems the @postConstruct on the extending class is called first (if the second is called at all). I then get a NPE on "context" because I'm assuming the super bean's PostConstruct has already been called.

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

Is this do-able? If so what am I doing wrong?

基础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);
}

谢谢, 约塔姆.

推荐答案

在构造托管bean时,根本不调用支持bean的超类的@PostConstruct.仅当例如通过构造该超类的完全独立的受管bean实例时才调用它.在您的情况下在EL中使用#{baseBean}.您实际上以两个完全独立的实例#{baseBean}#{smartBoxSearchBean}结尾,其中实例的自己的@PostConstruct方法是在托管bean类本身上独立调用的.

The @PostConstruct of the superclass of a backing bean is not called at all when the managed bean is constructed. It's only called when a completely separate managed bean instance of that superclass is been constructed by e.g. using #{baseBean} in EL in your case. You effectively end up with two entirely separate instances #{baseBean} and #{smartBoxSearchBean} wherein the class' own @PostConstruct method is invoked independently on the managed bean class itself.

这种设计有些奇怪.通常根本不将支持bean的超类用作托管bean.

This design is somewhat strange. A superclass of a backing bean is normally not to be used as a managed bean at all.

我建议如下修改您的方法:

I suggest to revise your approach as follows:

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用于其他目的

Or maybe this, if you don't need ContextBean for other purposes at all

public abstract class BaseBean {

    @ManagedProperty("#{contextBean.context}")
    private Context context;

    public Context getContext() {
        return context;
    }

}

请注意,当以这种方式在超类中声明时,@ManagedProperty可以很好地工作.

Note that @ManagedProperty works just fine when declared in a superclass this way.

更新:根据功能要求,还可以将Bean分离,只需将#{baseBean}注入{smartBoxSearchBean}中即可.

Update: depending on the functional requirements, you can also decouple the beans and just inject the #{baseBean} in the {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);
    }

}

这篇关于在超级bean和扩展bean上调用@PostConstruct的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆