【问题标题】:How to invoke a method in @SessionScoped bean from @ApplicationScoped bean如何从@ApplicationScoped bean调用@SessionScoped bean中的方法
【发布时间】:2014-10-28 13:22:15
【问题描述】:

有没有办法获得对@SessionScoped bean 的引用并从@ApplicationScoped bean 调用它的方法?

BeanManager.getContext() 在请求期间有效,但在请求之外看起来却不起作用。我在GlobalHttpSessionController 中保留了一个活动的 HttpSessions 列表,但这似乎没有任何帮助。谢谢你们的cmets。

@ApplicationScoped
public class MyAppScopedClass {

    @Inject
    GlobalHttpSessionController globalHttpSessionController;

    @Inject
    BeanManager beanManager;

    public void updateSessions() {
        // List of active user sessions
        List<HttpSession> session = globalHttpSessionController.getSessions();
        Set<Bean<?>> set = beanManager.getBeans(UserSessionBean.class);

        for (Bean bean : set) {
            ((UserSessionBean) beanManager.getContext(bean.getScope()).get(bean, beanManager.createCreationalContext(bean))).method();
        }
    }

}

【问题讨论】:

  • 我可以看到你想要做什么。如果您的应用程序分布在两台或多台服务器上,您是否考虑过这将如何正常工作?
  • 我知道这不会扩展。是的,我正在尝试以某种方式实现全局事件。
  • 你可以试试javax.enterprise.event中的Java EE事件处理机制。
  • @SteveC,很遗憾,CDI 事件从 ApplicationScoped 到 SessionScoped 不起作用。

标签: java cdi java-ee-6


【解决方案1】:

您可以尝试模仿 Spring MVC。当您在单例范围的 bean 中注入 SessionScoped bean 时,它会注入一个代理,该代理在执行时使用当前会话中的 bean。因为没有它,您会在创建应用程序范围的 bean 时获得一个 bean,并且只能访问那个。

编辑:

看起来要从其上下文中提取会话 bean 并不容易(即当它的会话不活动时)。因此,您应该将 bean 的引用存储为会话属性,以便以后能够轻松地检索它。

但我认为您想要的是事件管理。不幸的是,我从未在 Java EE CDI 环境中使用过它。

【讨论】:

  • 恐怕SessionScoped bean 的一个实例是不够的。我想在不发起请求的情况下获得所有这些。
  • @grapa :如果要保留活动会话列表,则需要 HttpSessionListener :您在 onCreate 事件中创建 bean 并将其存储在应用程序范围的 bean 中,然后删除它在onDestroy 事件中。
  • 谢谢@Serge,但这里的问题是通知会话,当我已经拥有它们时。
  • @grapa :如果 bean 被存储为会话属性,你不能用 session.getAttribute("beanName") 得到它吗? (我更习惯 Spring 会话范围的 bean 默认存储为会话属性)
  • 在创建过程中存储 SessionScoped bean 时,我可以稍后从 ApplicationScoped bean 访问它们。我想我得检查一下这些 cdi bean 是否被钝化了。
【解决方案2】:

您可以使用 Instance 来访问较低范围内的 bean。您的 Application 范围 bean 将包含 Session 范围 bean 的供应商,您仅在需要时访问它。然后,您将在那一刻获得会话的 bean 实例。

@Inject
private Instance<MySessionScopedBean> beanInstance;

public void doStuff() {
   beanInstance.get().useMethodOfSessionScopedBean();
}

【讨论】:

  • 这很有趣,但是我需要在用户请求之外调用该方法(实际上最合适的是在Web服务调用期间执行该方法)。此时存在活动的用户会话。如果我按照您的建议注入参考,它会以 No active contexts for scope type javax.enterprise.context.SessionScoped Exception 结束
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-04
  • 2013-12-07
相关资源
最近更新 更多