【发布时间】:2018-08-05 05:24:45
【问题描述】:
我有两个使用@Named 的bean,一个使用@SessionScoped,另一个使用@ViewScoped。我可以将@ViewScoped bean 注入@SessionScoped 并尝试做相反的事情,我几乎可以工作,但我没有相同的实例。
当我在 viewScoped Bean 的 @PostContruct 方法中打印 this.hashcode() 并将其与 sessionScoped Bean 中注入的比较时,我可以看到它。
所以我找到了一个解决方案,但我不知道这是否是一个好习惯:在注入 SessionScoped bean 后,在 ViewScoped bean 的 @PostContruct 方法中,我通过 à setter 将 ViewScoped 发送到 SessionScoped。
如果我充分理解这些对象与用户相关联,所以不会造成任何麻烦,对吗?
@Named
@ViewScoped
public class ViewScopedBean {
@Inject
protected SessionScopedBean sessionScopedBean;
@PostContruct
public void init(){
sessionScopedBean.setViewScopedBean(this);
}
}
@Named
@SessionScoped
public class SessionScopedBean {
protected ViewScopedBean viewScopedBean ;
public void setViewScopedBean(ViewScopedBean viewScopedBean){
this.viewScopedBean = viewScopedBean;
}
}
【问题讨论】:
-
这里需要注意两点。首先,你得到的那两个视图范围的bean实际上是不同的吗?请记住,它们(很可能)是代理,因此请使用它们的内部状态而不是
hashCode(可以在代理级别调用)来验证它。其次 - 你确定你足够了解ViewScoped生命周期吗?例如。您得到两个不同的实例可能是合乎逻辑的,因为它绑定到 JSF 视图。另见this answer -
谢谢你的回答,你是对的!我检查了一下,它是嵌入在代理中的同一个对象。如果我在 Injected ViewScopedBean 上调用哈希码,我会看到代理的哈希码,但如果我调用嵌入式 bean 的方法(将哈希码打印到),我可以看到它是相同的。关于生命周期,我认为是这样,但我不知道所有细节(我应该 ^^),我使用 ViewScoped Bean 来保持 primefaces 树组件的状态,可以使用延迟加载扩展节点。
-
使用旧的 ManagedBean 系统,我无法使用 @ManagedProperty 注释将 viewScopedBean 注入到 sessionScopedBean 中。但在这里我很想知道它是如何工作的。我想任何时候 ViewScopedBean 更改它都会重新注入到 SessionScopedBean 中,对吗?
-
我不熟悉视图范围的实现细节,但从 CDI 的角度来看(视图范围来自 JSF),您应该始终在给定的上下文和线程中注入当前活动的(如果有的话)视图范围 bean .该底层视图范围 bean 的创建/替换是由 JSF impl 强制执行的,并且应该在创建/退出视图时发生。
-
我已将评论提取到答案中,以便可以解决这个 SO 问题。
标签: jsf cdi named-scope