CDI SessionScoped bean的非延迟实例化

时间:2013-11-13 17:52:31

标签: jsf jsf-2 cdi

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

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

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

我看到的另一个选择是选择一个会话bean(由EL中的JSF或其他bean的引用进行100%初始化),并使用其@PostConstruct触发其他会话bean的方法 - 这个解决方案比前一个更糟糕。

看起来我在这里遗漏了一些东西,我很欣赏其他任何想法。

2 个答案:

答案 0 :(得分:3)

在接受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
  }
}

答案 1 :(得分:1)

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

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

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