CDI新手问题。简单的测试场景:JSF + CDI SessionScoped bean。
我需要一种优雅的方式来实例化一组已知的会话作用域CDI bean,而不必在JSF
页面上提及它们或从其他bean调用它们的方法。作为测试用例 - 一个简单的日志记录bean,它只记录http会话的开始和结束时间。
当然,我可以创建一个空的JSF组件,将它放在站点范围的模板中,并使其触发所需会话bean的虚拟方法,但它对我的pov来说有点难看。
我看到的另一个选择是选择一个会话bean(由EL
中的JSF
或其他bean的引用进行100%初始化),并使用其@PostConstruct
触发其他会话bean的方法 - 这个解决方案比前一个更糟糕。
看起来我在这里遗漏了一些东西,我很欣赏其他任何想法。
答案 0 :(得分:3)
在接受Karl的回答并感谢Luiggi的提示时,我也发布了基于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
}
}
答案 1 :(得分:1)
是的,HttpSessionListener
会这样做。只需注入bean并调用它们。
如果容器不支持HttpSessionListener中的注入,你可以查看deltaspike core和BeanProvider