通知所有用户的所有@ SessionScoped-Beans-Instances

时间:2014-08-27 15:07:08

标签: jsf cdi

我的问题

我有@SessionScoped sessionInformationBean,其中包含来自已登录用户的Person - 实体。因此,如果用户登录,我正在查找相应的Entity并输入@SessionScoped CDI Bean。此Bean用于在代码中的任何位置检索当前用户(Person - 实体),以便您可以检查,如果它是管理员或类似的东西。

@Inject
private PersonFacade personFacade;

private Person currentUser;

public Person getCurrentUser() {
    if (currentUser == null) {
        String loginname = FacesContext.
        getCurrentInstance().
        getExternalContext().getRemoteUser();  
        currentUser = personFacade.findByLoginname(loginname);
    }

    return currentUser;
}

但是设置案例,管理员正在为这个登录用户(Person - 实体)提供一些管理员权限并将他保存到数据库中。在这种情况下,Person Bean中的@SessionScoped未更新,因此已刷新页面后,已登录的用户未看到其管理员权限。那就是问题所在。为了避免这个问题,我每次访问时都会从数据库中获取new(没有激活缓存)到@SessionScoped bean。

我想要什么

但是我想缓存他并且每次都避免访问数据库。所以,我想,如果有人保存用户,我只会注意到所有sessionInformationBean - 实例,并将currentUser - 属性设置为null。因此,在下一次调用时,他们会再次从数据库中获取它并将其缓存,直到从null - 操作再次设置为Person.save()

我尝试了什么

但这似乎有点棘手。我以为我可以用CDI-Events处理它,但它们只会被推送到用户的sessionInformationBean,即编辑其他用户。

可能与我的问题有关:CDI Events observed across sessions

然后我想......好吧..让我们用Primefaces-Push做吧。但同样的事情......事件只是来到我自己的sessionInformationBean

EventBus eventBus = EventBusFactory.getDefault().eventBus();
eventBus.publish("/session", "test");

我认为推送和WebSockets的目的是通知所有用户或会话。

我该怎么办?

所以,问题是:如何访问特定@SessionScoped Bean的所有实例?我只想访问每个登录用户的sessionInformationBean,并将currentUser设置为null

1 个答案:

答案 0 :(得分:1)

没有内置的方法,我可以想到这样做。我建议添加一个ApplicationScoped bean。每当创建SessionScoped bean时,请使用此应用程序作用域bean注册它。当您想要处理此事件时,请遍历所有这些对象。

我很好奇,当你有多台服务器时会发生什么?