CDI 会话范围 bean 的非延迟实例化



CDI新手问题。简单的测试场景:JSF + CDI SessionScoped bean。

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

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

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

看起来我在这里错过了一些东西,我将不胜感激任何其他想法。

在接受卡尔的回答并感谢路易吉的提示的同时,我也发布了我的解决方案,该解决方案基于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
  }
}

是的,HttpSessionListener会这样做。只需注入豆子并调用它们。

如果你的容器不支持在 HttpSessionListener 中注入,你可以看看 deltaspike 核心和BeanProvider

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

最新更新