当前位置: 首页 > 知识库问答 >
问题:

CDI会话范围bean的非惰性实例化

尹赞
2023-03-14

CDI新手问题。简单测试场景:JSF CDI会话范围bean。

我需要一种优雅的方式来实例化一组已知的会话范围的cdibean,而不必在JSF页面上提及它们,也不必从其他bean调用它们的方法。作为一个测试用例——一个简单的日志bean,它只记录http会话的开始和结束时间。

当然,我可以创建一个空的JSF组件,将其放在站点范围的模板中,并使其触发所需会话bean的虚拟方法,但从我的观点来看,这有点难看。

我看到的另一个选项是选择一个会话bean(在JSF中通过EL或通过其他bean的引用100%初始化),并使用其@PostConstruct方法触发其他会话bean-该解决方案比前一个稍微简单一些。

看起来我错过了什么,我希望有其他的想法。

共有2个答案

家经纶
2023-03-14

是的,HttpSessionListener可以。只需注入bean并调用它们。

如果您的容器不支持HttpSessionListener中的注入,您可以查看deltaspike core和BeanProvider

http://deltaspike.apache.org/core.html

空俊语
2023-03-14

在接受Karl的回答并感谢Luiggi的提示的同时,我还发布了我的解决方案,该解决方案基于HttpSessionListener,但不需要与BeanProviderBeanManager混为一谈。

@WebListener
public class SessionListener implements HttpSessionListener {

  @Inject
  Event<SessionStartEvent> startEvent;
  @Inject
  Event<SessionEndEvent> endEvent;

  @Override
  public void sessionCreated(HttpSessionEvent se) {
    SessionStartEvent e = new SessionStartEvent();
    startEvent.fire(e);
  }

  @Override
  public void sessionDestroyed(HttpSessionEvent se) {
    SessionEndEvent e = new SessionEndEvent();
    endEvent.fire(e);
  }
}

令我惊讶的是,上面的代码实例化了所有bean,哪些方法正在观察这些事件:

@Named
@SessionScoped
public class SessionLogger implements Serializable {

  @PostConstruct
  public void init() {
    // is called first
  }

  public void start(@Observes SessionStartEvent event) {
    // is called second
  }
}

 类似资料:
  • 我有一个@SessionScoped CDIBean,用于跟踪web应用程序中的用户会话信息。有没有办法从另一个@ApplicationScoped bean中找到这个bean的所有对象?

  • 在用户登录时续订HTTP会话是常见的最佳做法。这将强制使用新的会话ID,从而避免会话固定漏洞。 当涉及@SessionScoped bean时,是否有使用CDI实现此功能的首选模式?困难在于,通过使当前HTTP会话无效,您将在下一个请求中获得不同的会话范围bean,但直到下一个请求。 例如,假设一个用于存储用户登录信息的会话bean: 和另一个用于管理登录的bean: 对于托管Bean,这将检索一

  • 我有一个会话范围的CDI托管bean: 在某个流之后,我需要从会话中删除这个bean,对于该流,我使用了以下代码,如下面的答案所示: 但是,它不起作用,仍然留在会话中。 我是否遗漏了什么?

  • tl;dr注入servlet的CDIBean如何可能也在适当的范围内? 在oracle官方教程和一些书籍中,我们可以看到一些简单的示例,展示如何将CDIBean注入servlet。这非常简单,因为我们只需要使用@Inject注释并在bean中启用bean发现。xml。我不明白的是,注入servlet的@RequestScoped或@SessionScoped bean的作用域是否正确。servle

  • 问题内容: 考虑以下请求范围的CDI bean: 现在,我将其注入到应用程序范围的bean中: 我运行了这段代码,并注意到两个请求之间的请求范围的Bean实例是不同的,但应用程序范围的Bean实例是相同的。我的疑问是:这如何运作?在每个请求时,是否将请求范围的Bean实例重新分配给应用程序范围的字段?还是应用程序范围的bean的代理只是在请求之间改变? 问题答案: 在CDI中,每个注入的对象实际上

  • HttpSession 对象必须被限定在应用(或 servlet 上下文)级别。底层的机制,如使用 cookie 建立会话,不同的上下文可以是相同,但所引用的对象,包括该对象中的属性,决不能在容器上下文之间共享。 用一个例子来说明该要求: 如果 servlet 使用 RequestDispatcher 来调用另一个 Web 应用的 servlet,任何创建的会话和被调用 servlet 所见的必须