【问题标题】:PostConstruct in CDI SessionScoped managed beansCDI SessionScoped 托管 bean 中的 PostConstruct
【发布时间】: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


【解决方案1】:

HttpSessionListener 是您最好的选择。您可以做的是将 SessionScoped 组件注入到侦听器中并在那里设置值。

【讨论】:

    猜你喜欢
    • 2012-02-04
    • 1970-01-01
    • 2015-04-20
    • 1970-01-01
    • 2016-07-09
    • 1970-01-01
    • 1970-01-01
    • 2011-06-18
    相关资源
    最近更新 更多