CDI新手问题。简单的测试场景:JSF + CDI SessionScoped bean。
我需要一种优雅的方式来实例化一组已知的会话范围的 CDI bean,而无需在 JSF
页面上提及它们或从其他 bean 调用它们的方法。作为测试用例 - 一个简单的日志记录 Bean,它只是记录 http 会话的开始和结束时间。
当然,我可以创建一个空的 JSF 组件,将其放置在站点范围的模板中,并使其触发所需会话 bean 的虚拟方法,但从我的 pov 来看,这有点丑陋。
我看到的另一个选项是选择一个单会话 bean(通过 JSF
中的EL
或通过来自其他 bean 的引用来 100% 初始化),并使用其 @PostConstruct
方法来触发其他会话 bean - 解决方案比前一个更丑陋一点。
看起来我在这里错过了一些东西,我将不胜感激任何其他想法。
在接受卡尔的回答并感谢路易吉的提示的同时,我也发布了我的解决方案,该解决方案基于HttpSessionListener
但不需要弄乱BeanProvider
或BeanManager
。
@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