【发布时间】:2013-05-10 11:06:35
【问题描述】:
简短的故事:我有一个名为 UserContextBean 的 CDI @SessionScoped bean(来自 javax.enterprise.context 而不是来自 javax.faces 的注释)。我想在创建 HTTP 会话时实际做一些事情。
所以我很自然地认为@PostConstruct 会成功:在构造这个bean 的实例时只调用一次。
但是,根据文档here,他们说调用了 PostConstruct 方法:
当托管 bean 被注入到组件中时,CDI 调用 在所有注入发生和所有初始化程序之后的方法 已被调用。
我曾假设每个会话都会调用一次 post 构造方法。但是,实践与文档一致。这个 bean 被注入到一个 @RequestScoped bean(也是 CDI)中,它作为 JSF 页面的支持 bean,每个请求都调用 PostConstruct 方法。
我(现在)意识到这就是行为。但是是否有任何其他方法可以为每个会话初始化一次?
一些代码,虽然不是很相关:
@Named(UserContextBean.BEAN_NAME)
@SessionScoped
public class UserContextBean implements Serializable {
...
@PostConstruct
private void createSession() {
System.out.println("UserContext created.");
}
}
我在其中注入的请求范围 bean:
public abstract class WebPageDataProvider extends AbstractViewDataProvider {
@Inject
private UserContextBean userContext;
我也在考虑使用HttpSessionListener 并初始化会话 bean,但听起来已经很乱了。
编辑
现在刚刚注意到甚至没有创建 HTTP 会话。如果我通过调用getSession(true)“手动”创建会话(出于测试目的,我在相位侦听器中执行此操作,但只是因为它已经存在),那么一切都会按预期工作。
【问题讨论】:
-
您的 UI 是如何构建的?
-
@JohnAment:嗯,它是 JSF 2 (Mojarra)。我正在测试的特定页面非常简单。它源自一个模板,只是将几个 facelets 组合在一起。使用请求范围 bean 的 EL 表达式在实际页面中,而不是在 facelets 中,并且只是访问 bean 中的文本属性(它使用用户上下文 bean 来获取用户角色)。
-
好的,很好。抱歉,CDI 实现和容器呢?如果您使用的是 tomcat,您是通过 servlet 使用 CDI 吗?
标签: jakarta-ee glassfish-3 cdi managed-bean weld